| 
									
										
										
										
											2017-05-19 15:59:25 -07:00
										 |  |  | import datetime | 
					
						
							| 
									
										
										
										
											2020-09-02 11:40:56 +05:30
										 |  |  | import os | 
					
						
							| 
									
										
										
										
											2021-07-26 07:40:39 +01:00
										 |  |  | from urllib.parse import urlparse, parse_qs | 
					
						
							| 
									
										
										
										
											2017-06-03 19:06:49 -04:00
										 |  |  | from gzip import GzipFile | 
					
						
							| 
									
										
										
										
											2013-03-26 14:52:33 +00:00
										 |  |  | from io import BytesIO | 
					
						
							| 
									
										
										
										
											2017-06-03 19:06:49 -04:00
										 |  |  | import zlib | 
					
						
							| 
									
										
										
										
											2018-12-20 11:15:15 -08:00
										 |  |  | import pickle | 
					
						
							| 
									
										
										
										
											2019-05-29 15:22:29 -05:00
										 |  |  | import uuid | 
					
						
							| 
									
										
										
										
											2013-02-27 01:12:11 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-23 17:33:52 -04:00
										 |  |  | import json | 
					
						
							| 
									
										
										
										
											2015-08-02 09:54:23 -04:00
										 |  |  | import boto3 | 
					
						
							| 
									
										
										
										
											2015-08-13 21:16:55 +00:00
										 |  |  | from botocore.client import ClientError | 
					
						
							| 
									
										
										
										
											2017-05-19 15:59:25 -07:00
										 |  |  | import botocore.exceptions | 
					
						
							| 
									
										
										
										
											2022-01-18 14:18:57 -01:00
										 |  |  | from botocore.handlers import disable_signing | 
					
						
							| 
									
										
										
										
											2013-03-29 17:45:33 -04:00
										 |  |  | from freezegun import freeze_time | 
					
						
							| 
									
										
										
										
											2013-02-25 23:21:49 -05:00
										 |  |  | import requests | 
					
						
							| 
									
										
										
										
											2021-06-10 05:48:28 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-09 11:41:57 +02:00
										 |  |  | from moto.moto_api import state_manager | 
					
						
							| 
									
										
										
										
											2020-02-02 10:36:51 +00:00
										 |  |  | from moto.s3.responses import DEFAULT_REGION_NAME | 
					
						
							| 
									
										
										
										
											2020-10-06 07:54:49 +02:00
										 |  |  | from unittest import SkipTest | 
					
						
							|  |  |  | import pytest | 
					
						
							| 
									
										
										
										
											2013-02-18 16:09:40 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-18 19:44:29 +00:00
										 |  |  | import sure  # noqa # pylint: disable=unused-import | 
					
						
							| 
									
										
										
										
											2013-02-18 17:17:19 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-24 20:42:38 -01:00
										 |  |  | from moto import settings, mock_s3, mock_config | 
					
						
							| 
									
										
										
										
											2017-02-23 19:43:48 -05:00
										 |  |  | import moto.s3.models as s3model | 
					
						
							| 
									
										
										
										
											2021-10-14 18:13:40 +00:00
										 |  |  | from uuid import uuid4 | 
					
						
							| 
									
										
										
										
											2020-02-27 08:54:57 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-10 13:19:45 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-18 16:09:40 -05:00
										 |  |  | class MyModel(object): | 
					
						
							| 
									
										
										
										
											2021-10-18 19:44:29 +00:00
										 |  |  |     def __init__(self, name, value, metadata=None): | 
					
						
							| 
									
										
										
										
											2013-02-18 16:09:40 -05:00
										 |  |  |         self.name = name | 
					
						
							|  |  |  |         self.value = value | 
					
						
							| 
									
										
										
										
											2021-10-18 19:44:29 +00:00
										 |  |  |         self.metadata = metadata or {} | 
					
						
							| 
									
										
										
										
											2013-02-18 16:09:40 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def save(self): | 
					
						
							| 
									
										
										
										
											2020-02-02 10:36:51 +00:00
										 |  |  |         s3 = boto3.client("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							| 
									
										
										
										
											2021-05-26 06:27:25 -07:00
										 |  |  |         s3.put_object( | 
					
						
							|  |  |  |             Bucket="mybucket", Key=self.name, Body=self.value, Metadata=self.metadata | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2013-02-18 16:09:40 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-20 11:15:15 -08:00
										 |  |  | @mock_s3 | 
					
						
							|  |  |  | def test_keys_are_pickleable(): | 
					
						
							|  |  |  |     """Keys must be pickleable due to boto3 implementation details.""" | 
					
						
							|  |  |  |     key = s3model.FakeKey("name", b"data!") | 
					
						
							| 
									
										
										
										
											2018-12-20 11:40:13 -08:00
										 |  |  |     assert key.value == b"data!" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-20 11:15:15 -08:00
										 |  |  |     pickled = pickle.dumps(key) | 
					
						
							|  |  |  |     loaded = pickle.loads(pickled) | 
					
						
							|  |  |  |     assert loaded.value == key.value | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-23 19:43:48 -05:00
										 |  |  | @mock_s3 | 
					
						
							| 
									
										
										
										
											2013-02-18 16:09:40 -05:00
										 |  |  | def test_my_model_save(): | 
					
						
							|  |  |  |     # Create Bucket so that test can run | 
					
						
							| 
									
										
										
										
											2020-02-02 10:36:51 +00:00
										 |  |  |     conn = boto3.resource("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							| 
									
										
										
										
											2017-02-23 19:43:48 -05:00
										 |  |  |     conn.create_bucket(Bucket="mybucket") | 
					
						
							| 
									
										
										
										
											2013-02-18 16:09:40 -05:00
										 |  |  |     #################################### | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     model_instance = MyModel("steve", "is awesome") | 
					
						
							|  |  |  |     model_instance.save() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-26 22:57:55 -07:00
										 |  |  |     body = conn.Object("mybucket", "steve").get()["Body"].read().decode() | 
					
						
							| 
									
										
										
										
											2017-02-23 19:43:48 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-23 22:28:09 -05:00
										 |  |  |     assert body == "is awesome" | 
					
						
							| 
									
										
										
										
											2013-02-18 17:17:19 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-18 21:22:03 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-26 06:27:25 -07:00
										 |  |  | @mock_s3 | 
					
						
							|  |  |  | def test_object_metadata(): | 
					
						
							|  |  |  |     """Metadata keys can contain certain special characters like dash and dot""" | 
					
						
							|  |  |  |     # Create Bucket so that test can run | 
					
						
							|  |  |  |     conn = boto3.resource("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							|  |  |  |     conn.create_bucket(Bucket="mybucket") | 
					
						
							|  |  |  |     #################################### | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     metadata = {"meta": "simple", "my-meta": "dash", "meta.data": "namespaced"} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     model_instance = MyModel("steve", "is awesome", metadata=metadata) | 
					
						
							|  |  |  |     model_instance.save() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     meta = conn.Object("mybucket", "steve").get()["Metadata"] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     assert meta == metadata | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-23 19:50:34 -05:00
										 |  |  | @mock_s3 | 
					
						
							| 
									
										
										
										
											2022-02-24 20:42:38 -01:00
										 |  |  | def test_resource_get_object_returns_etag(): | 
					
						
							| 
									
										
										
										
											2020-02-02 10:36:51 +00:00
										 |  |  |     conn = boto3.resource("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							| 
									
										
										
										
											2017-02-23 19:50:34 -05:00
										 |  |  |     conn.create_bucket(Bucket="mybucket") | 
					
						
							| 
									
										
										
										
											2014-04-02 14:40:04 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  |     model_instance = MyModel("steve", "is awesome") | 
					
						
							|  |  |  |     model_instance.save() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-23 19:50:34 -05:00
										 |  |  |     conn.Bucket("mybucket").Object("steve").e_tag.should.equal( | 
					
						
							| 
									
										
										
										
											2014-04-02 14:40:04 +03:00
										 |  |  |         '"d32bda93738f7e03adb22e66c90fbc04"' | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-21 20:06:42 +00:00
										 |  |  | @mock_s3 | 
					
						
							| 
									
										
										
										
											2022-02-24 20:42:38 -01:00
										 |  |  | def test_key_save_to_missing_bucket(): | 
					
						
							| 
									
										
										
										
											2021-09-21 20:06:42 +00:00
										 |  |  |     s3 = boto3.resource("s3") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     key = s3.Object("mybucket", "the-key") | 
					
						
							|  |  |  |     with pytest.raises(ClientError) as ex: | 
					
						
							|  |  |  |         key.put(Body=b"foobar") | 
					
						
							|  |  |  |     ex.value.response["Error"]["Code"].should.equal("NoSuchBucket") | 
					
						
							|  |  |  |     ex.value.response["Error"]["Message"].should.equal( | 
					
						
							|  |  |  |         "The specified bucket does not exist" | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_s3 | 
					
						
							| 
									
										
										
										
											2022-02-24 20:42:38 -01:00
										 |  |  | def test_missing_key_request(): | 
					
						
							| 
									
										
										
										
											2022-02-08 15:35:37 -01:00
										 |  |  |     if settings.TEST_SERVER_MODE: | 
					
						
							|  |  |  |         raise SkipTest("Only test status code in non-ServerMode") | 
					
						
							| 
									
										
										
										
											2021-09-21 20:06:42 +00:00
										 |  |  |     s3 = boto3.client("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							|  |  |  |     s3.create_bucket(Bucket="foobar") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     response = requests.get("http://foobar.s3.amazonaws.com/the-key") | 
					
						
							| 
									
										
										
										
											2022-02-08 15:35:37 -01:00
										 |  |  |     response.status_code.should.equal(404) | 
					
						
							| 
									
										
										
										
											2021-09-21 20:06:42 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_s3 | 
					
						
							| 
									
										
										
										
											2022-02-24 20:42:38 -01:00
										 |  |  | def test_empty_key(): | 
					
						
							| 
									
										
										
										
											2021-09-21 20:06:42 +00:00
										 |  |  |     s3 = boto3.resource("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							|  |  |  |     client = boto3.client("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							|  |  |  |     s3.create_bucket(Bucket="foobar") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     key = s3.Object("foobar", "the-key") | 
					
						
							|  |  |  |     key.put(Body=b"") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     resp = client.get_object(Bucket="foobar", Key="the-key") | 
					
						
							|  |  |  |     resp.should.have.key("ContentLength").equal(0) | 
					
						
							|  |  |  |     resp["Body"].read().should.equal(b"") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-01 06:03:40 -05:00
										 |  |  | @mock_s3 | 
					
						
							|  |  |  | def test_key_name_encoding_in_listing(): | 
					
						
							|  |  |  |     s3 = boto3.resource("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							|  |  |  |     client = boto3.client("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							|  |  |  |     s3.create_bucket(Bucket="foobar") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     name = "6T7\x159\x12\r\x08.txt" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     key = s3.Object("foobar", name) | 
					
						
							|  |  |  |     key.put(Body=b"") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     key_received = client.list_objects(Bucket="foobar")["Contents"][0]["Key"] | 
					
						
							|  |  |  |     key_received.should.equal(name) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     key_received = client.list_objects_v2(Bucket="foobar")["Contents"][0]["Key"] | 
					
						
							|  |  |  |     key_received.should.equal(name) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-24 17:55:20 -05:00
										 |  |  |     name = "example/file.text" | 
					
						
							|  |  |  |     client.put_object(Bucket="foobar", Key=name, Body=b"") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     key_received = client.list_objects( | 
					
						
							|  |  |  |         Bucket="foobar", Prefix="example/", Delimiter="/", MaxKeys=1, EncodingType="url" | 
					
						
							|  |  |  |     )["Contents"][0]["Key"] | 
					
						
							|  |  |  |     key_received.should.equal(name) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-01 06:03:40 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-21 20:06:42 +00:00
										 |  |  | @mock_s3 | 
					
						
							| 
									
										
										
										
											2022-02-24 20:42:38 -01:00
										 |  |  | def test_empty_key_set_on_existing_key(): | 
					
						
							| 
									
										
										
										
											2021-09-21 20:06:42 +00:00
										 |  |  |     s3 = boto3.resource("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							|  |  |  |     client = boto3.client("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							|  |  |  |     s3.create_bucket(Bucket="foobar") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     key = s3.Object("foobar", "the-key") | 
					
						
							|  |  |  |     key.put(Body=b"some content") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     resp = client.get_object(Bucket="foobar", Key="the-key") | 
					
						
							|  |  |  |     resp.should.have.key("ContentLength").equal(12) | 
					
						
							|  |  |  |     resp["Body"].read().should.equal(b"some content") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     key.put(Body=b"") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     resp = client.get_object(Bucket="foobar", Key="the-key") | 
					
						
							|  |  |  |     resp.should.have.key("ContentLength").equal(0) | 
					
						
							|  |  |  |     resp["Body"].read().should.equal(b"") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_s3 | 
					
						
							| 
									
										
										
										
											2022-02-24 20:42:38 -01:00
										 |  |  | def test_large_key_save(): | 
					
						
							| 
									
										
										
										
											2021-09-21 20:06:42 +00:00
										 |  |  |     s3 = boto3.resource("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							|  |  |  |     client = boto3.client("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							|  |  |  |     s3.create_bucket(Bucket="foobar") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     key = s3.Object("foobar", "the-key") | 
					
						
							|  |  |  |     key.put(Body=b"foobar" * 100000) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     resp = client.get_object(Bucket="foobar", Key="the-key") | 
					
						
							|  |  |  |     resp["Body"].read().should.equal(b"foobar" * 100000) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_s3 | 
					
						
							| 
									
										
										
										
											2022-02-24 20:42:38 -01:00
										 |  |  | def test_set_metadata(): | 
					
						
							| 
									
										
										
										
											2021-09-21 20:06:42 +00:00
										 |  |  |     s3 = boto3.resource("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							|  |  |  |     client = boto3.client("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							|  |  |  |     s3.create_bucket(Bucket="foobar") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     key = s3.Object("foobar", "the-key") | 
					
						
							|  |  |  |     key.put(Body=b"some value", Metadata={"md": "Metadatastring"}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     resp = client.get_object(Bucket="foobar", Key="the-key") | 
					
						
							|  |  |  |     resp["Metadata"].should.equal({"md": "Metadatastring"}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @freeze_time("2012-01-01 12:00:00") | 
					
						
							|  |  |  | @mock_s3 | 
					
						
							| 
									
										
										
										
											2022-02-24 20:42:38 -01:00
										 |  |  | def test_last_modified(): | 
					
						
							| 
									
										
										
										
											2021-09-21 20:06:42 +00:00
										 |  |  |     # See https://github.com/boto/boto/issues/466 | 
					
						
							|  |  |  |     s3 = boto3.resource("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							|  |  |  |     client = boto3.client("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							|  |  |  |     s3.create_bucket(Bucket="foobar") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     key = s3.Object("foobar", "the-key") | 
					
						
							|  |  |  |     key.put(Body=b"some value", Metadata={"md": "Metadatastring"}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     rs = client.list_objects_v2(Bucket="foobar")["Contents"] | 
					
						
							|  |  |  |     rs[0]["LastModified"].should.be.a(datetime.datetime) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     resp = client.get_object(Bucket="foobar", Key="the-key") | 
					
						
							|  |  |  |     resp["LastModified"].should.be.a(datetime.datetime) | 
					
						
							|  |  |  |     as_header = resp["ResponseMetadata"]["HTTPHeaders"]["last-modified"] | 
					
						
							|  |  |  |     as_header.should.be.a(str) | 
					
						
							|  |  |  |     if not settings.TEST_SERVER_MODE: | 
					
						
							|  |  |  |         as_header.should.equal("Sun, 01 Jan 2012 12:00:00 GMT") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_s3 | 
					
						
							| 
									
										
										
										
											2022-02-24 20:42:38 -01:00
										 |  |  | def test_missing_bucket(): | 
					
						
							| 
									
										
										
										
											2021-09-21 20:06:42 +00:00
										 |  |  |     client = boto3.client("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							|  |  |  |     with pytest.raises(ClientError) as ex: | 
					
						
							|  |  |  |         client.head_bucket(Bucket="mybucket") | 
					
						
							|  |  |  |     ex.value.response["Error"]["Code"].should.equal("404") | 
					
						
							|  |  |  |     ex.value.response["Error"]["Message"].should.equal("Not Found") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     with pytest.raises(ClientError) as ex: | 
					
						
							|  |  |  |         client.head_bucket(Bucket="dash-in-name") | 
					
						
							|  |  |  |     ex.value.response["Error"]["Code"].should.equal("404") | 
					
						
							|  |  |  |     ex.value.response["Error"]["Message"].should.equal("Not Found") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_s3 | 
					
						
							| 
									
										
										
										
											2022-02-24 20:42:38 -01:00
										 |  |  | def test_create_existing_bucket(): | 
					
						
							| 
									
										
										
										
											2021-09-21 20:06:42 +00:00
										 |  |  |     "Trying to create a bucket that already exists should raise an Error" | 
					
						
							|  |  |  |     client = boto3.client("s3", region_name="us-west-2") | 
					
						
							|  |  |  |     kwargs = { | 
					
						
							|  |  |  |         "Bucket": "foobar", | 
					
						
							|  |  |  |         "CreateBucketConfiguration": {"LocationConstraint": "us-west-2"}, | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     client.create_bucket(**kwargs) | 
					
						
							|  |  |  |     with pytest.raises(ClientError) as ex: | 
					
						
							|  |  |  |         client.create_bucket(**kwargs) | 
					
						
							|  |  |  |     ex.value.response["Error"]["Code"].should.equal("BucketAlreadyOwnedByYou") | 
					
						
							|  |  |  |     ex.value.response["Error"]["Message"].should.equal( | 
					
						
							|  |  |  |         "Your previous request to create the named bucket succeeded and you already own it." | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_s3 | 
					
						
							| 
									
										
										
										
											2022-02-24 20:42:38 -01:00
										 |  |  | def test_create_existing_bucket_in_us_east_1(): | 
					
						
							| 
									
										
										
										
											2021-09-21 20:06:42 +00:00
										 |  |  |     "Trying to create a bucket that already exists in us-east-1 returns the bucket" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     """"
 | 
					
						
							|  |  |  |     http://docs.aws.amazon.com/AmazonS3/latest/API/ErrorResponses.html | 
					
						
							|  |  |  |     Your previous request to create the named bucket succeeded and you already | 
					
						
							|  |  |  |     own it. You get this error in all AWS regions except US Standard, | 
					
						
							|  |  |  |     us-east-1. In us-east-1 region, you will get 200 OK, but it is no-op (if | 
					
						
							|  |  |  |     bucket exists it Amazon S3 will not do anything). | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     client = boto3.client("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							|  |  |  |     client.create_bucket(Bucket="foobar") | 
					
						
							|  |  |  |     client.create_bucket(Bucket="foobar") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_s3 | 
					
						
							| 
									
										
										
										
											2022-02-24 20:42:38 -01:00
										 |  |  | def test_bucket_deletion(): | 
					
						
							| 
									
										
										
										
											2021-09-21 20:06:42 +00:00
										 |  |  |     s3 = boto3.resource("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							|  |  |  |     client = boto3.client("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							|  |  |  |     client.create_bucket(Bucket="foobar") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     key = s3.Object("foobar", "the-key") | 
					
						
							|  |  |  |     key.put(Body=b"some value") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Try to delete a bucket that still has keys | 
					
						
							|  |  |  |     with pytest.raises(ClientError) as ex: | 
					
						
							|  |  |  |         client.delete_bucket(Bucket="foobar") | 
					
						
							|  |  |  |     ex.value.response["Error"]["Code"].should.equal("BucketNotEmpty") | 
					
						
							|  |  |  |     ex.value.response["Error"]["Message"].should.equal( | 
					
						
							|  |  |  |         "The bucket you tried to delete is not empty" | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     client.delete_object(Bucket="foobar", Key="the-key") | 
					
						
							|  |  |  |     client.delete_bucket(Bucket="foobar") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Delete non-existent bucket | 
					
						
							|  |  |  |     with pytest.raises(ClientError) as ex: | 
					
						
							|  |  |  |         client.delete_bucket(Bucket="foobar") | 
					
						
							|  |  |  |     ex.value.response["Error"]["Code"].should.equal("NoSuchBucket") | 
					
						
							|  |  |  |     ex.value.response["Error"]["Message"].should.equal( | 
					
						
							|  |  |  |         "The specified bucket does not exist" | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_s3 | 
					
						
							| 
									
										
										
										
											2022-02-24 20:42:38 -01:00
										 |  |  | def test_get_all_buckets(): | 
					
						
							| 
									
										
										
										
											2021-09-21 20:06:42 +00:00
										 |  |  |     client = boto3.client("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							|  |  |  |     client.create_bucket(Bucket="foobar") | 
					
						
							|  |  |  |     client.create_bucket(Bucket="foobar2") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     client.list_buckets()["Buckets"].should.have.length_of(2) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_s3 | 
					
						
							| 
									
										
										
										
											2022-02-24 20:42:38 -01:00
										 |  |  | def test_post_to_bucket(): | 
					
						
							| 
									
										
										
										
											2021-09-21 20:06:42 +00:00
										 |  |  |     if settings.TEST_SERVER_MODE: | 
					
						
							|  |  |  |         # ServerMode does not allow unauthorized requests | 
					
						
							|  |  |  |         raise SkipTest() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     client = boto3.client("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							|  |  |  |     client.create_bucket(Bucket="foobar") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     requests.post( | 
					
						
							|  |  |  |         "https://foobar.s3.amazonaws.com/", {"key": "the-key", "file": "nothing"} | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     resp = client.get_object(Bucket="foobar", Key="the-key") | 
					
						
							|  |  |  |     resp["Body"].read().should.equal(b"nothing") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_s3 | 
					
						
							| 
									
										
										
										
											2022-02-24 20:42:38 -01:00
										 |  |  | def test_post_with_metadata_to_bucket(): | 
					
						
							| 
									
										
										
										
											2021-09-21 20:06:42 +00:00
										 |  |  |     if settings.TEST_SERVER_MODE: | 
					
						
							|  |  |  |         # ServerMode does not allow unauthorized requests | 
					
						
							|  |  |  |         raise SkipTest() | 
					
						
							|  |  |  |     client = boto3.client("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							|  |  |  |     client.create_bucket(Bucket="foobar") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     requests.post( | 
					
						
							|  |  |  |         "https://foobar.s3.amazonaws.com/", | 
					
						
							|  |  |  |         {"key": "the-key", "file": "nothing", "x-amz-meta-test": "metadata"}, | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     resp = client.get_object(Bucket="foobar", Key="the-key") | 
					
						
							|  |  |  |     resp["Metadata"].should.equal({"test": "metadata"}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-15 14:25:34 -06:00
										 |  |  | @mock_s3 | 
					
						
							|  |  |  | def test_delete_versioned_objects(): | 
					
						
							|  |  |  |     s3 = boto3.client("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							|  |  |  |     bucket = "test" | 
					
						
							|  |  |  |     key = "test" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     s3.create_bucket(Bucket=bucket) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     s3.put_object(Bucket=bucket, Key=key, Body=b"") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     s3.put_bucket_versioning( | 
					
						
							|  |  |  |         Bucket=bucket, VersioningConfiguration={"Status": "Enabled"} | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     objects = s3.list_objects_v2(Bucket=bucket).get("Contents") | 
					
						
							|  |  |  |     versions = s3.list_object_versions(Bucket=bucket).get("Versions") | 
					
						
							|  |  |  |     delete_markers = s3.list_object_versions(Bucket=bucket).get("DeleteMarkers") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-18 20:44:56 +00:00
										 |  |  |     objects.should.have.length_of(1) | 
					
						
							|  |  |  |     versions.should.have.length_of(1) | 
					
						
							|  |  |  |     delete_markers.should.equal(None) | 
					
						
							| 
									
										
										
										
											2021-11-15 14:25:34 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  |     s3.delete_object(Bucket=bucket, Key=key) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     objects = s3.list_objects_v2(Bucket=bucket).get("Contents") | 
					
						
							|  |  |  |     versions = s3.list_object_versions(Bucket=bucket).get("Versions") | 
					
						
							|  |  |  |     delete_markers = s3.list_object_versions(Bucket=bucket).get("DeleteMarkers") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-18 20:44:56 +00:00
										 |  |  |     objects.should.equal(None) | 
					
						
							|  |  |  |     versions.should.have.length_of(1) | 
					
						
							|  |  |  |     delete_markers.should.have.length_of(1) | 
					
						
							| 
									
										
										
										
											2021-11-15 14:25:34 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  |     s3.delete_object(Bucket=bucket, Key=key, VersionId=versions[0].get("VersionId")) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     objects = s3.list_objects_v2(Bucket=bucket).get("Contents") | 
					
						
							|  |  |  |     versions = s3.list_object_versions(Bucket=bucket).get("Versions") | 
					
						
							|  |  |  |     delete_markers = s3.list_object_versions(Bucket=bucket).get("DeleteMarkers") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-18 20:44:56 +00:00
										 |  |  |     objects.should.equal(None) | 
					
						
							|  |  |  |     versions.should.equal(None) | 
					
						
							|  |  |  |     delete_markers.should.have.length_of(1) | 
					
						
							| 
									
										
										
										
											2021-11-15 14:25:34 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  |     s3.delete_object( | 
					
						
							|  |  |  |         Bucket=bucket, Key=key, VersionId=delete_markers[0].get("VersionId") | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     objects = s3.list_objects_v2(Bucket=bucket).get("Contents") | 
					
						
							|  |  |  |     versions = s3.list_object_versions(Bucket=bucket).get("Versions") | 
					
						
							|  |  |  |     delete_markers = s3.list_object_versions(Bucket=bucket).get("DeleteMarkers") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-18 20:44:56 +00:00
										 |  |  |     objects.should.equal(None) | 
					
						
							|  |  |  |     versions.should.equal(None) | 
					
						
							|  |  |  |     delete_markers.should.equal(None) | 
					
						
							| 
									
										
										
										
											2021-11-15 14:25:34 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-21 20:06:42 +00:00
										 |  |  | @mock_s3 | 
					
						
							| 
									
										
										
										
											2022-02-24 20:42:38 -01:00
										 |  |  | def test_delete_missing_key(): | 
					
						
							| 
									
										
										
										
											2021-09-21 20:06:42 +00:00
										 |  |  |     s3 = boto3.resource("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							|  |  |  |     bucket = s3.Bucket("foobar") | 
					
						
							|  |  |  |     bucket.create() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     s3.Object("foobar", "key1").put(Body=b"some value") | 
					
						
							|  |  |  |     s3.Object("foobar", "key2").put(Body=b"some value") | 
					
						
							|  |  |  |     s3.Object("foobar", "key3").put(Body=b"some value") | 
					
						
							|  |  |  |     s3.Object("foobar", "key4").put(Body=b"some value") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     result = bucket.delete_objects( | 
					
						
							|  |  |  |         Delete={ | 
					
						
							|  |  |  |             "Objects": [ | 
					
						
							|  |  |  |                 {"Key": "unknown"}, | 
					
						
							|  |  |  |                 {"Key": "key1"}, | 
					
						
							|  |  |  |                 {"Key": "key3"}, | 
					
						
							|  |  |  |                 {"Key": "typo"}, | 
					
						
							|  |  |  |             ] | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     result.should.have.key("Deleted").equal( | 
					
						
							|  |  |  |         [{"Key": "unknown"}, {"Key": "key1"}, {"Key": "key3"}, {"Key": "typo"}] | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     result.shouldnt.have.key("Errors") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     objects = list(bucket.objects.all()) | 
					
						
							|  |  |  |     set([o.key for o in objects]).should.equal(set(["key2", "key4"])) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-23 20:53:45 +02:00
										 |  |  | @mock_s3 | 
					
						
							| 
									
										
										
										
											2022-02-24 20:42:38 -01:00
										 |  |  | def test_delete_empty_keys_list(): | 
					
						
							| 
									
										
										
										
											2020-10-06 07:54:49 +02:00
										 |  |  |     with pytest.raises(ClientError) as err: | 
					
						
							| 
									
										
										
										
											2019-06-18 12:36:32 +00:00
										 |  |  |         boto3.client("s3").delete_objects(Bucket="foobar", Delete={"Objects": []}) | 
					
						
							| 
									
										
										
										
											2020-10-06 08:04:09 +02:00
										 |  |  |     assert err.value.response["Error"]["Code"] == "MalformedXML" | 
					
						
							| 
									
										
										
										
											2019-06-18 12:36:32 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-08 20:35:48 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-18 14:18:57 -01:00
										 |  |  | @pytest.mark.parametrize("name", ["firstname.lastname", "with-dash"]) | 
					
						
							| 
									
										
										
										
											2021-09-21 20:06:42 +00:00
										 |  |  | @mock_s3 | 
					
						
							| 
									
										
										
										
											2022-02-24 20:42:38 -01:00
										 |  |  | def test_bucket_name_with_special_chars(name): | 
					
						
							| 
									
										
										
										
											2021-09-21 20:06:42 +00:00
										 |  |  |     s3 = boto3.resource("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							|  |  |  |     client = boto3.client("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							| 
									
										
										
										
											2022-01-18 14:18:57 -01:00
										 |  |  |     bucket = s3.Bucket(name) | 
					
						
							| 
									
										
										
										
											2021-09-21 20:06:42 +00:00
										 |  |  |     bucket.create() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-18 14:18:57 -01:00
										 |  |  |     s3.Object(name, "the-key").put(Body=b"some value") | 
					
						
							| 
									
										
										
										
											2021-09-21 20:06:42 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-18 14:18:57 -01:00
										 |  |  |     resp = client.get_object(Bucket=name, Key="the-key") | 
					
						
							| 
									
										
										
										
											2021-09-21 20:06:42 +00:00
										 |  |  |     resp["Body"].read().should.equal(b"some value") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @pytest.mark.parametrize( | 
					
						
							|  |  |  |     "key", ["normal", "test_list_keys_2/x?y", "/the-key-unîcode/test"] | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | @mock_s3 | 
					
						
							| 
									
										
										
										
											2022-02-24 20:42:38 -01:00
										 |  |  | def test_key_with_special_characters(key): | 
					
						
							| 
									
										
										
										
											2021-09-21 20:06:42 +00:00
										 |  |  |     s3 = boto3.resource("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							|  |  |  |     client = boto3.client("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							|  |  |  |     bucket = s3.Bucket("testname") | 
					
						
							|  |  |  |     bucket.create() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     s3.Object("testname", key).put(Body=b"value") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     objects = list(bucket.objects.all()) | 
					
						
							|  |  |  |     [o.key for o in objects].should.equal([key]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     resp = client.get_object(Bucket="testname", Key=key) | 
					
						
							|  |  |  |     resp["Body"].read().should.equal(b"value") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_s3 | 
					
						
							| 
									
										
										
										
											2022-02-24 20:42:38 -01:00
										 |  |  | def test_bucket_key_listing_order(): | 
					
						
							| 
									
										
										
										
											2021-09-21 20:06:42 +00:00
										 |  |  |     s3 = boto3.resource("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							|  |  |  |     bucket_name = "test_bucket" | 
					
						
							|  |  |  |     bucket = s3.Bucket(bucket_name) | 
					
						
							|  |  |  |     bucket.create() | 
					
						
							|  |  |  |     prefix = "toplevel/" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     names = ["x/key", "y.key1", "y.key2", "y.key3", "x/y/key", "x/y/z/key"] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for name in names: | 
					
						
							|  |  |  |         s3.Object(bucket_name, prefix + name).put(Body=b"somedata") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     delimiter = "" | 
					
						
							|  |  |  |     keys = [x.key for x in bucket.objects.filter(Prefix=prefix, Delimiter=delimiter)] | 
					
						
							|  |  |  |     keys.should.equal( | 
					
						
							|  |  |  |         [ | 
					
						
							|  |  |  |             "toplevel/x/key", | 
					
						
							|  |  |  |             "toplevel/x/y/key", | 
					
						
							|  |  |  |             "toplevel/x/y/z/key", | 
					
						
							|  |  |  |             "toplevel/y.key1", | 
					
						
							|  |  |  |             "toplevel/y.key2", | 
					
						
							|  |  |  |             "toplevel/y.key3", | 
					
						
							|  |  |  |         ] | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     delimiter = "/" | 
					
						
							|  |  |  |     keys = [x.key for x in bucket.objects.filter(Prefix=prefix, Delimiter=delimiter)] | 
					
						
							|  |  |  |     keys.should.equal(["toplevel/y.key1", "toplevel/y.key2", "toplevel/y.key3"]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Test delimiter with no prefix | 
					
						
							|  |  |  |     keys = [x.key for x in bucket.objects.filter(Delimiter=delimiter)] | 
					
						
							|  |  |  |     keys.should.equal([]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     prefix = "toplevel/x" | 
					
						
							|  |  |  |     keys = [x.key for x in bucket.objects.filter(Prefix=prefix)] | 
					
						
							|  |  |  |     keys.should.equal(["toplevel/x/key", "toplevel/x/y/key", "toplevel/x/y/z/key"]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     keys = [x.key for x in bucket.objects.filter(Prefix=prefix, Delimiter=delimiter)] | 
					
						
							|  |  |  |     keys.should.equal([]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_s3 | 
					
						
							| 
									
										
										
										
											2022-02-24 20:42:38 -01:00
										 |  |  | def test_key_with_reduced_redundancy(): | 
					
						
							| 
									
										
										
										
											2021-09-21 20:06:42 +00:00
										 |  |  |     s3 = boto3.resource("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							|  |  |  |     bucket_name = "test_bucket" | 
					
						
							|  |  |  |     bucket = s3.Bucket(bucket_name) | 
					
						
							|  |  |  |     bucket.create() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     bucket.put_object( | 
					
						
							|  |  |  |         Key="test_rr_key", Body=b"somedata", StorageClass="REDUCED_REDUNDANCY" | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # we use the bucket iterator because of: | 
					
						
							|  |  |  |     # https:/github.com/boto/boto/issues/1173 | 
					
						
							|  |  |  |     [x.storage_class for x in bucket.objects.all()].should.equal(["REDUCED_REDUNDANCY"]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @freeze_time("2012-01-01 12:00:00") | 
					
						
							|  |  |  | @mock_s3 | 
					
						
							| 
									
										
										
										
											2022-02-24 20:42:38 -01:00
										 |  |  | def test_restore_key(): | 
					
						
							| 
									
										
										
										
											2021-09-21 20:06:42 +00:00
										 |  |  |     s3 = boto3.resource("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							|  |  |  |     bucket = s3.Bucket("foobar") | 
					
						
							|  |  |  |     bucket.create() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-07 22:00:42 +09:00
										 |  |  |     key = bucket.put_object(Key="the-key", Body=b"somedata", StorageClass="GLACIER") | 
					
						
							| 
									
										
										
										
											2022-04-18 20:44:56 +00:00
										 |  |  |     key.restore.should.equal(None) | 
					
						
							| 
									
										
										
										
											2021-09-21 20:06:42 +00:00
										 |  |  |     key.restore_object(RestoreRequest={"Days": 1}) | 
					
						
							|  |  |  |     if settings.TEST_SERVER_MODE: | 
					
						
							|  |  |  |         key.restore.should.contain('ongoing-request="false"') | 
					
						
							|  |  |  |     else: | 
					
						
							|  |  |  |         key.restore.should.equal( | 
					
						
							|  |  |  |             'ongoing-request="false", expiry-date="Mon, 02 Jan 2012 12:00:00 GMT"' | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     key.restore_object(RestoreRequest={"Days": 2}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if settings.TEST_SERVER_MODE: | 
					
						
							|  |  |  |         key.restore.should.contain('ongoing-request="false"') | 
					
						
							|  |  |  |     else: | 
					
						
							|  |  |  |         key.restore.should.equal( | 
					
						
							|  |  |  |             'ongoing-request="false", expiry-date="Tue, 03 Jan 2012 12:00:00 GMT"' | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-09 11:41:57 +02:00
										 |  |  | @freeze_time("2012-01-01 12:00:00") | 
					
						
							|  |  |  | @mock_s3 | 
					
						
							|  |  |  | def test_restore_key_transition(): | 
					
						
							|  |  |  |     if settings.TEST_SERVER_MODE: | 
					
						
							|  |  |  |         raise SkipTest("Can't set transition directly in ServerMode") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     state_manager.set_transition( | 
					
						
							|  |  |  |         model_name="s3::keyrestore", transition={"progression": "manual", "times": 1} | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     s3 = boto3.resource("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							|  |  |  |     bucket = s3.Bucket("foobar") | 
					
						
							|  |  |  |     bucket.create() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     key = bucket.put_object(Key="the-key", Body=b"somedata", StorageClass="GLACIER") | 
					
						
							|  |  |  |     key.restore.should.equal(None) | 
					
						
							|  |  |  |     key.restore_object(RestoreRequest={"Days": 1}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # first call: there should be an ongoing request | 
					
						
							|  |  |  |     key.restore.should.contain('ongoing-request="true"') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # second call: request should be done | 
					
						
							|  |  |  |     key.load() | 
					
						
							|  |  |  |     key.restore.should.contain('ongoing-request="false"') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # third call: request should still be done | 
					
						
							|  |  |  |     key.load() | 
					
						
							|  |  |  |     key.restore.should.contain('ongoing-request="false"') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     state_manager.unset_transition(model_name="s3::keyrestore") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-07 22:00:42 +09:00
										 |  |  | @mock_s3 | 
					
						
							| 
									
										
										
										
											2022-02-24 20:42:38 -01:00
										 |  |  | def test_cannot_restore_standard_class_object(): | 
					
						
							| 
									
										
										
										
											2021-12-07 22:00:42 +09:00
										 |  |  |     s3 = boto3.resource("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							|  |  |  |     bucket = s3.Bucket("foobar") | 
					
						
							|  |  |  |     bucket.create() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     key = bucket.put_object(Key="the-key", Body=b"somedata") | 
					
						
							|  |  |  |     with pytest.raises(Exception) as err: | 
					
						
							|  |  |  |         key.restore_object(RestoreRequest={"Days": 1}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     err = err.value.response["Error"] | 
					
						
							|  |  |  |     err["Code"].should.equal("InvalidObjectState") | 
					
						
							|  |  |  |     err["StorageClass"].should.equal("STANDARD") | 
					
						
							|  |  |  |     err["Message"].should.equal( | 
					
						
							|  |  |  |         "The operation is not valid for the object's storage class" | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-21 20:06:42 +00:00
										 |  |  | @mock_s3 | 
					
						
							| 
									
										
										
										
											2022-02-24 20:42:38 -01:00
										 |  |  | def test_get_versioning_status(): | 
					
						
							| 
									
										
										
										
											2021-09-21 20:06:42 +00:00
										 |  |  |     s3 = boto3.resource("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							|  |  |  |     bucket = s3.Bucket("foobar") | 
					
						
							|  |  |  |     bucket.create() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     v = s3.BucketVersioning("foobar") | 
					
						
							| 
									
										
										
										
											2022-04-18 20:44:56 +00:00
										 |  |  |     v.status.should.equal(None) | 
					
						
							| 
									
										
										
										
											2021-09-21 20:06:42 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     v.enable() | 
					
						
							|  |  |  |     v.status.should.equal("Enabled") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     v.suspend() | 
					
						
							|  |  |  |     v.status.should.equal("Suspended") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_s3 | 
					
						
							| 
									
										
										
										
											2022-02-24 20:42:38 -01:00
										 |  |  | def test_key_version(): | 
					
						
							| 
									
										
										
										
											2021-09-21 20:06:42 +00:00
										 |  |  |     s3 = boto3.resource("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							|  |  |  |     client = boto3.client("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							|  |  |  |     bucket = s3.Bucket("foobar") | 
					
						
							|  |  |  |     bucket.create() | 
					
						
							|  |  |  |     bucket.Versioning().enable() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     versions = [] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     key = bucket.put_object(Key="the-key", Body=b"somedata") | 
					
						
							|  |  |  |     versions.append(key.version_id) | 
					
						
							|  |  |  |     key.put(Body=b"some string") | 
					
						
							|  |  |  |     versions.append(key.version_id) | 
					
						
							|  |  |  |     set(versions).should.have.length_of(2) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     key = client.get_object(Bucket="foobar", Key="the-key") | 
					
						
							|  |  |  |     key["VersionId"].should.equal(versions[-1]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_s3 | 
					
						
							| 
									
										
										
										
											2022-02-24 20:42:38 -01:00
										 |  |  | def test_list_versions(): | 
					
						
							| 
									
										
										
										
											2021-09-21 20:06:42 +00:00
										 |  |  |     s3 = boto3.resource("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							|  |  |  |     client = boto3.client("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							|  |  |  |     bucket = s3.Bucket("foobar") | 
					
						
							|  |  |  |     bucket.create() | 
					
						
							|  |  |  |     bucket.Versioning().enable() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     key_versions = [] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     key = bucket.put_object(Key="the-key", Body=b"Version 1") | 
					
						
							|  |  |  |     key_versions.append(key.version_id) | 
					
						
							|  |  |  |     key = bucket.put_object(Key="the-key", Body=b"Version 2") | 
					
						
							|  |  |  |     key_versions.append(key.version_id) | 
					
						
							|  |  |  |     key_versions.should.have.length_of(2) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     versions = client.list_object_versions(Bucket="foobar")["Versions"] | 
					
						
							|  |  |  |     versions.should.have.length_of(2) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     versions[0]["Key"].should.equal("the-key") | 
					
						
							|  |  |  |     versions[0]["VersionId"].should.equal(key_versions[1]) | 
					
						
							|  |  |  |     resp = client.get_object(Bucket="foobar", Key="the-key") | 
					
						
							|  |  |  |     resp["Body"].read().should.equal(b"Version 2") | 
					
						
							|  |  |  |     resp = client.get_object( | 
					
						
							|  |  |  |         Bucket="foobar", Key="the-key", VersionId=versions[0]["VersionId"] | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     resp["Body"].read().should.equal(b"Version 2") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     versions[1]["Key"].should.equal("the-key") | 
					
						
							|  |  |  |     versions[1]["VersionId"].should.equal(key_versions[0]) | 
					
						
							|  |  |  |     resp = client.get_object( | 
					
						
							|  |  |  |         Bucket="foobar", Key="the-key", VersionId=versions[1]["VersionId"] | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     resp["Body"].read().should.equal(b"Version 1") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     bucket.put_object(Key="the2-key", Body=b"Version 1") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     list(bucket.objects.all()).should.have.length_of(2) | 
					
						
							|  |  |  |     versions = client.list_object_versions(Bucket="foobar", Prefix="the2")["Versions"] | 
					
						
							|  |  |  |     versions.should.have.length_of(1) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-18 14:18:57 -01:00
										 |  |  | @mock_s3 | 
					
						
							| 
									
										
										
										
											2022-02-24 20:42:38 -01:00
										 |  |  | def test_acl_setting(): | 
					
						
							| 
									
										
										
										
											2022-01-18 14:18:57 -01:00
										 |  |  |     s3 = boto3.resource("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							|  |  |  |     client = boto3.client("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							|  |  |  |     bucket = s3.Bucket("foobar") | 
					
						
							|  |  |  |     bucket.create() | 
					
						
							| 
									
										
										
										
											2015-10-07 00:04:22 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     content = b"imafile" | 
					
						
							|  |  |  |     keyname = "test.txt" | 
					
						
							| 
									
										
										
										
											2022-01-18 14:18:57 -01:00
										 |  |  |     bucket.put_object( | 
					
						
							|  |  |  |         Key=keyname, Body=content, ContentType="text/plain", ACL="public-read" | 
					
						
							| 
									
										
										
										
											2015-10-07 00:04:22 -07:00
										 |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-18 14:18:57 -01:00
										 |  |  |     grants = client.get_object_acl(Bucket="foobar", Key=keyname)["Grants"] | 
					
						
							|  |  |  |     grants.should.contain( | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             "Grantee": { | 
					
						
							|  |  |  |                 "Type": "Group", | 
					
						
							|  |  |  |                 "URI": "http://acs.amazonaws.com/groups/global/AllUsers", | 
					
						
							|  |  |  |             }, | 
					
						
							|  |  |  |             "Permission": "READ", | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2015-10-07 00:04:22 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-18 14:18:57 -01:00
										 |  |  | @mock_s3 | 
					
						
							| 
									
										
										
										
											2022-02-24 20:42:38 -01:00
										 |  |  | def test_acl_setting_via_headers(): | 
					
						
							| 
									
										
										
										
											2022-01-18 14:18:57 -01:00
										 |  |  |     s3 = boto3.resource("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							|  |  |  |     client = boto3.client("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							|  |  |  |     bucket = s3.Bucket("foobar") | 
					
						
							|  |  |  |     bucket.create() | 
					
						
							| 
									
										
										
										
											2015-10-07 00:04:22 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     keyname = "test.txt" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-18 14:18:57 -01:00
										 |  |  |     bucket.put_object(Key=keyname, Body=b"imafile") | 
					
						
							|  |  |  |     client.put_object_acl(ACL="public-read", Bucket="foobar", Key=keyname) | 
					
						
							| 
									
										
										
										
											2015-10-07 00:04:22 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-18 14:18:57 -01:00
										 |  |  |     grants = client.get_object_acl(Bucket="foobar", Key=keyname)["Grants"] | 
					
						
							|  |  |  |     grants.should.contain( | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             "Grantee": { | 
					
						
							|  |  |  |                 "Type": "Group", | 
					
						
							|  |  |  |                 "URI": "http://acs.amazonaws.com/groups/global/AllUsers", | 
					
						
							|  |  |  |             }, | 
					
						
							|  |  |  |             "Permission": "READ", | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2015-10-07 00:04:22 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-22 10:19:56 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-18 14:18:57 -01:00
										 |  |  | @mock_s3 | 
					
						
							| 
									
										
										
										
											2022-02-24 20:42:38 -01:00
										 |  |  | def test_acl_switching(): | 
					
						
							| 
									
										
										
										
											2022-01-18 14:18:57 -01:00
										 |  |  |     s3 = boto3.resource("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							|  |  |  |     client = boto3.client("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							|  |  |  |     bucket = s3.Bucket("foobar") | 
					
						
							|  |  |  |     bucket.create() | 
					
						
							|  |  |  |     keyname = "test.txt" | 
					
						
							| 
									
										
										
										
											2015-11-11 20:26:29 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-18 14:18:57 -01:00
										 |  |  |     bucket.put_object(Key=keyname, Body=b"asdf", ACL="public-read") | 
					
						
							|  |  |  |     client.put_object_acl(ACL="private", Bucket="foobar", Key=keyname) | 
					
						
							| 
									
										
										
										
											2015-11-11 20:26:29 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-18 14:18:57 -01:00
										 |  |  |     grants = client.get_object_acl(Bucket="foobar", Key=keyname)["Grants"] | 
					
						
							|  |  |  |     grants.shouldnt.contain( | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             "Grantee": { | 
					
						
							|  |  |  |                 "Type": "Group", | 
					
						
							|  |  |  |                 "URI": "http://acs.amazonaws.com/groups/global/AllUsers", | 
					
						
							|  |  |  |             }, | 
					
						
							|  |  |  |             "Permission": "READ", | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2015-11-11 20:26:29 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-18 14:18:57 -01:00
										 |  |  | @mock_s3 | 
					
						
							|  |  |  | def test_acl_switching_nonexistent_key(): | 
					
						
							|  |  |  |     s3 = boto3.client("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							|  |  |  |     s3.create_bucket(Bucket="mybucket") | 
					
						
							| 
									
										
										
										
											2015-11-11 20:26:29 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-18 14:18:57 -01:00
										 |  |  |     with pytest.raises(ClientError) as e: | 
					
						
							|  |  |  |         s3.put_object_acl(Bucket="mybucket", Key="nonexistent", ACL="private") | 
					
						
							| 
									
										
										
										
											2015-11-11 20:26:29 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-18 14:18:57 -01:00
										 |  |  |     e.value.response["Error"]["Code"].should.equal("NoSuchKey") | 
					
						
							| 
									
										
										
										
											2015-11-11 20:26:29 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-11 01:50:50 -04:00
										 |  |  | @mock_s3 | 
					
						
							|  |  |  | def test_streaming_upload_from_file_to_presigned_url(): | 
					
						
							| 
									
										
										
										
											2020-06-19 11:44:43 +01:00
										 |  |  |     s3 = boto3.resource("s3", region_name="us-east-1") | 
					
						
							| 
									
										
										
										
											2020-06-11 01:50:50 -04:00
										 |  |  |     bucket = s3.Bucket("test-bucket") | 
					
						
							|  |  |  |     bucket.create() | 
					
						
							|  |  |  |     bucket.put_object(Body=b"ABCD", Key="file.txt") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     params = {"Bucket": "test-bucket", "Key": "file.txt"} | 
					
						
							|  |  |  |     presigned_url = boto3.client("s3").generate_presigned_url( | 
					
						
							|  |  |  |         "put_object", params, ExpiresIn=900 | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     with open(__file__, "rb") as f: | 
					
						
							|  |  |  |         response = requests.get(presigned_url, data=f) | 
					
						
							|  |  |  |     assert response.status_code == 200 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-02 11:40:56 +05:30
										 |  |  | @mock_s3 | 
					
						
							| 
									
										
										
										
											2022-02-24 20:42:38 -01:00
										 |  |  | def test_upload_from_file_to_presigned_url(): | 
					
						
							| 
									
										
										
										
											2020-09-02 11:40:56 +05:30
										 |  |  |     s3 = boto3.client("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							|  |  |  |     s3.create_bucket(Bucket="mybucket") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     params = {"Bucket": "mybucket", "Key": "file_upload"} | 
					
						
							|  |  |  |     presigned_url = boto3.client("s3").generate_presigned_url( | 
					
						
							|  |  |  |         "put_object", params, ExpiresIn=900 | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     file = open("text.txt", "w") | 
					
						
							|  |  |  |     file.write("test") | 
					
						
							|  |  |  |     file.close() | 
					
						
							|  |  |  |     files = {"upload_file": open("text.txt", "rb")} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     requests.put(presigned_url, files=files) | 
					
						
							|  |  |  |     resp = s3.get_object(Bucket="mybucket", Key="file_upload") | 
					
						
							|  |  |  |     data = resp["Body"].read() | 
					
						
							|  |  |  |     assert data == b"test" | 
					
						
							|  |  |  |     # cleanup | 
					
						
							|  |  |  |     os.remove("text.txt") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-28 09:33:27 +00:00
										 |  |  | @mock_s3 | 
					
						
							|  |  |  | def test_upload_file_with_checksum_algorithm(): | 
					
						
							|  |  |  |     random_bytes = b"\xff\xd8\xff\xe0\x00\x10JFIF\x00\x01\x01\x00\x00\x01\x00\x01\x00\x00\xff\n\xdb\x00C\x00\x08\x06\x06\x07\x06\x05\x08\x07\x07\n" | 
					
						
							|  |  |  |     with open("rb.tmp", mode="wb") as f: | 
					
						
							|  |  |  |         f.write(random_bytes) | 
					
						
							|  |  |  |     s3 = boto3.resource("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							|  |  |  |     s3_client = boto3.client("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							|  |  |  |     bucket = "mybucket" | 
					
						
							|  |  |  |     s3_client.create_bucket(Bucket=bucket) | 
					
						
							|  |  |  |     s3_client.upload_file( | 
					
						
							|  |  |  |         "rb.tmp", bucket, "my_key.csv", ExtraArgs={"ChecksumAlgorithm": "SHA256"} | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     os.remove("rb.tmp") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     actual_content = s3.Object(bucket, "my_key.csv").get()["Body"].read() | 
					
						
							|  |  |  |     assert random_bytes == actual_content | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-19 16:06:43 +02:00
										 |  |  | @mock_s3 | 
					
						
							|  |  |  | def test_put_chunked_with_v4_signature_in_body(): | 
					
						
							|  |  |  |     bucket_name = "mybucket" | 
					
						
							|  |  |  |     file_name = "file" | 
					
						
							|  |  |  |     content = "CONTENT" | 
					
						
							|  |  |  |     content_bytes = bytes(content, encoding="utf8") | 
					
						
							|  |  |  |     # 'CONTENT' as received in moto, when PutObject is called in java AWS SDK v2 | 
					
						
							|  |  |  |     chunked_body = b"7;chunk-signature=bd479c607ec05dd9d570893f74eed76a4b333dfa37ad6446f631ec47dc52e756\r\nCONTENT\r\n0;chunk-signature=d192ec4075ddfc18d2ef4da4f55a87dc762ba4417b3bd41e70c282f8bec2ece0\r\n\r\n" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     s3 = boto3.client("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							|  |  |  |     s3.create_bucket(Bucket=bucket_name) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     model = MyModel(file_name, content) | 
					
						
							|  |  |  |     model.save() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     boto_etag = s3.get_object(Bucket=bucket_name, Key=file_name)["ETag"] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     params = {"Bucket": bucket_name, "Key": file_name} | 
					
						
							|  |  |  |     # We'll use manipulated presigned PUT, to mimick PUT from SDK | 
					
						
							|  |  |  |     presigned_url = boto3.client("s3").generate_presigned_url( | 
					
						
							|  |  |  |         "put_object", params, ExpiresIn=900 | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     requests.put( | 
					
						
							|  |  |  |         presigned_url, | 
					
						
							|  |  |  |         data=chunked_body, | 
					
						
							|  |  |  |         headers={ | 
					
						
							|  |  |  |             "Content-Type": "application/octet-stream", | 
					
						
							|  |  |  |             "x-amz-content-sha256": "STREAMING-AWS4-HMAC-SHA256-PAYLOAD", | 
					
						
							|  |  |  |             "x-amz-decoded-content-length": str(len(content_bytes)), | 
					
						
							|  |  |  |         }, | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     resp = s3.get_object(Bucket=bucket_name, Key=file_name) | 
					
						
							|  |  |  |     body = resp["Body"].read() | 
					
						
							|  |  |  |     assert body == content_bytes | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     etag = resp["ETag"] | 
					
						
							|  |  |  |     assert etag == boto_etag | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-18 14:18:57 -01:00
										 |  |  | @mock_s3 | 
					
						
							|  |  |  | def test_s3_object_in_private_bucket(): | 
					
						
							|  |  |  |     s3 = boto3.resource("s3") | 
					
						
							|  |  |  |     bucket = s3.Bucket("test-bucket") | 
					
						
							|  |  |  |     bucket.create( | 
					
						
							|  |  |  |         ACL="private", CreateBucketConfiguration={"LocationConstraint": "us-west-1"} | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     bucket.put_object(ACL="private", Body=b"ABCD", Key="file.txt") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     s3_anonymous = boto3.resource("s3") | 
					
						
							|  |  |  |     s3_anonymous.meta.client.meta.events.register("choose-signer.s3.*", disable_signing) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     with pytest.raises(ClientError) as exc: | 
					
						
							|  |  |  |         s3_anonymous.Object(key="file.txt", bucket_name="test-bucket").get() | 
					
						
							|  |  |  |     exc.value.response["Error"]["Code"].should.equal("403") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     bucket.put_object(ACL="public-read", Body=b"ABCD", Key="file.txt") | 
					
						
							|  |  |  |     contents = ( | 
					
						
							|  |  |  |         s3_anonymous.Object(key="file.txt", bucket_name="test-bucket") | 
					
						
							|  |  |  |         .get()["Body"] | 
					
						
							|  |  |  |         .read() | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     contents.should.equal(b"ABCD") | 
					
						
							| 
									
										
										
										
											2014-11-22 10:19:56 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-21 20:06:42 +00:00
										 |  |  | @mock_s3 | 
					
						
							| 
									
										
										
										
											2022-02-24 20:42:38 -01:00
										 |  |  | def test_unicode_key(): | 
					
						
							| 
									
										
										
										
											2021-09-21 20:06:42 +00:00
										 |  |  |     s3 = boto3.resource("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							|  |  |  |     bucket = s3.Bucket("mybucket") | 
					
						
							|  |  |  |     bucket.create() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     key = bucket.put_object(Key="こんにちは.jpg", Body=b"Hello world!") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     [listed_key.key for listed_key in bucket.objects.all()].should.equal([key.key]) | 
					
						
							|  |  |  |     fetched_key = s3.Object("mybucket", key.key) | 
					
						
							|  |  |  |     fetched_key.key.should.equal(key.key) | 
					
						
							|  |  |  |     fetched_key.get()["Body"].read().decode("utf-8").should.equal("Hello world!") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_s3 | 
					
						
							| 
									
										
										
										
											2022-02-24 20:42:38 -01:00
										 |  |  | def test_unicode_value(): | 
					
						
							| 
									
										
										
										
											2021-09-21 20:06:42 +00:00
										 |  |  |     s3 = boto3.resource("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							|  |  |  |     bucket = s3.Bucket("mybucket") | 
					
						
							|  |  |  |     bucket.create() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     bucket.put_object(Key="some_key", Body="こんにちは.jpg") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     key = s3.Object("mybucket", "some_key") | 
					
						
							|  |  |  |     key.get()["Body"].read().decode("utf-8").should.equal("こんにちは.jpg") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_s3 | 
					
						
							| 
									
										
										
										
											2022-02-24 20:42:38 -01:00
										 |  |  | def test_setting_content_encoding(): | 
					
						
							| 
									
										
										
										
											2021-09-21 20:06:42 +00:00
										 |  |  |     s3 = boto3.resource("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							|  |  |  |     bucket = s3.Bucket("mybucket") | 
					
						
							|  |  |  |     bucket.create() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     bucket.put_object(Body=b"abcdef", ContentEncoding="gzip", Key="keyname") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     key = s3.Object("mybucket", "keyname") | 
					
						
							|  |  |  |     key.content_encoding.should.equal("gzip") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-29 07:07:29 -05:00
										 |  |  | @mock_s3 | 
					
						
							| 
									
										
										
										
											2020-02-02 10:36:51 +00:00
										 |  |  | def test_bucket_location_default(): | 
					
						
							|  |  |  |     cli = boto3.client("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							| 
									
										
										
										
											2018-11-20 19:42:51 +01:00
										 |  |  |     bucket_name = "mybucket" | 
					
						
							|  |  |  |     # No LocationConstraint ==> us-east-1 | 
					
						
							|  |  |  |     cli.create_bucket(Bucket=bucket_name) | 
					
						
							|  |  |  |     cli.get_bucket_location(Bucket=bucket_name)["LocationConstraint"].should.equal(None) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-02 10:36:51 +00:00
										 |  |  | @mock_s3 | 
					
						
							|  |  |  | def test_bucket_location_nondefault(): | 
					
						
							|  |  |  |     cli = boto3.client("s3", region_name="eu-central-1") | 
					
						
							|  |  |  |     bucket_name = "mybucket" | 
					
						
							|  |  |  |     # LocationConstraint set for non default regions | 
					
						
							| 
									
										
										
										
											2021-10-18 19:44:29 +00:00
										 |  |  |     cli.create_bucket( | 
					
						
							| 
									
										
										
										
											2020-02-02 10:36:51 +00:00
										 |  |  |         Bucket=bucket_name, | 
					
						
							|  |  |  |         CreateBucketConfiguration={"LocationConstraint": "eu-central-1"}, | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     cli.get_bucket_location(Bucket=bucket_name)["LocationConstraint"].should.equal( | 
					
						
							|  |  |  |         "eu-central-1" | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-31 05:47:29 -05:00
										 |  |  | @mock_s3 | 
					
						
							|  |  |  | def test_s3_location_should_error_outside_useast1(): | 
					
						
							|  |  |  |     s3 = boto3.client("s3", region_name="eu-west-1") | 
					
						
							| 
									
										
										
										
											2020-02-02 12:45:57 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-31 05:47:29 -05:00
										 |  |  |     bucket_name = "asdfasdfsdfdsfasda" | 
					
						
							| 
									
										
										
										
											2020-02-02 12:45:57 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-31 05:47:29 -05:00
										 |  |  |     with pytest.raises(ClientError) as e: | 
					
						
							|  |  |  |         s3.create_bucket(Bucket=bucket_name) | 
					
						
							|  |  |  |     e.value.response["Error"]["Message"].should.equal( | 
					
						
							|  |  |  |         "The unspecified location constraint is incompatible for the region specific endpoint this request was sent to." | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2020-02-02 10:36:51 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-21 20:06:42 +00:00
										 |  |  | @mock_s3 | 
					
						
							| 
									
										
										
										
											2022-02-24 20:42:38 -01:00
										 |  |  | def test_ranged_get(): | 
					
						
							| 
									
										
										
										
											2021-09-21 20:06:42 +00:00
										 |  |  |     s3 = boto3.resource("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							|  |  |  |     bucket = s3.Bucket("mybucket") | 
					
						
							|  |  |  |     bucket.create() | 
					
						
							|  |  |  |     rep = b"0123456789" | 
					
						
							|  |  |  |     key = bucket.put_object(Key="bigkey", Body=rep * 10) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Implicitly bounded range requests. | 
					
						
							|  |  |  |     key.get(Range="bytes=0-")["Body"].read().should.equal(rep * 10) | 
					
						
							|  |  |  |     key.get(Range="bytes=50-")["Body"].read().should.equal(rep * 5) | 
					
						
							|  |  |  |     key.get(Range="bytes=99-")["Body"].read().should.equal(b"9") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Explicitly bounded range requests starting from the first byte. | 
					
						
							|  |  |  |     key.get(Range="bytes=0-0")["Body"].read().should.equal(b"0") | 
					
						
							|  |  |  |     key.get(Range="bytes=0-49")["Body"].read().should.equal(rep * 5) | 
					
						
							|  |  |  |     key.get(Range="bytes=0-99")["Body"].read().should.equal(rep * 10) | 
					
						
							|  |  |  |     key.get(Range="bytes=0-100")["Body"].read().should.equal(rep * 10) | 
					
						
							|  |  |  |     key.get(Range="bytes=0-700")["Body"].read().should.equal(rep * 10) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Explicitly bounded range requests starting from the / a middle byte. | 
					
						
							|  |  |  |     key.get(Range="bytes=50-54")["Body"].read().should.equal(rep[:5]) | 
					
						
							|  |  |  |     key.get(Range="bytes=50-99")["Body"].read().should.equal(rep * 5) | 
					
						
							|  |  |  |     key.get(Range="bytes=50-100")["Body"].read().should.equal(rep * 5) | 
					
						
							|  |  |  |     key.get(Range="bytes=50-700")["Body"].read().should.equal(rep * 5) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Explicitly bounded range requests starting from the last byte. | 
					
						
							|  |  |  |     key.get(Range="bytes=99-99")["Body"].read().should.equal(b"9") | 
					
						
							|  |  |  |     key.get(Range="bytes=99-100")["Body"].read().should.equal(b"9") | 
					
						
							|  |  |  |     key.get(Range="bytes=99-700")["Body"].read().should.equal(b"9") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Suffix range requests. | 
					
						
							|  |  |  |     key.get(Range="bytes=-1")["Body"].read().should.equal(b"9") | 
					
						
							|  |  |  |     key.get(Range="bytes=-60")["Body"].read().should.equal(rep * 6) | 
					
						
							|  |  |  |     key.get(Range="bytes=-100")["Body"].read().should.equal(rep * 10) | 
					
						
							|  |  |  |     key.get(Range="bytes=-101")["Body"].read().should.equal(rep * 10) | 
					
						
							|  |  |  |     key.get(Range="bytes=-700")["Body"].read().should.equal(rep * 10) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     key.content_length.should.equal(100) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_s3 | 
					
						
							| 
									
										
										
										
											2022-02-24 20:42:38 -01:00
										 |  |  | def test_policy(): | 
					
						
							| 
									
										
										
										
											2021-09-21 20:06:42 +00:00
										 |  |  |     s3 = boto3.resource("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							|  |  |  |     client = boto3.client("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							|  |  |  |     bucket_name = "mybucket" | 
					
						
							|  |  |  |     bucket = s3.Bucket(bucket_name) | 
					
						
							|  |  |  |     bucket.create() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     policy = json.dumps( | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             "Version": "2012-10-17", | 
					
						
							|  |  |  |             "Id": "PutObjPolicy", | 
					
						
							|  |  |  |             "Statement": [ | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                     "Sid": "DenyUnEncryptedObjectUploads", | 
					
						
							|  |  |  |                     "Effect": "Deny", | 
					
						
							|  |  |  |                     "Principal": "*", | 
					
						
							|  |  |  |                     "Action": "s3:PutObject", | 
					
						
							| 
									
										
										
										
											2022-11-17 21:41:08 -01:00
										 |  |  |                     "Resource": f"arn:aws:s3:::{bucket_name}/*", | 
					
						
							| 
									
										
										
										
											2021-09-21 20:06:42 +00:00
										 |  |  |                     "Condition": { | 
					
						
							|  |  |  |                         "StringNotEquals": { | 
					
						
							|  |  |  |                             "s3:x-amz-server-side-encryption": "aws:kms" | 
					
						
							|  |  |  |                         } | 
					
						
							|  |  |  |                     }, | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             ], | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     with pytest.raises(ClientError) as ex: | 
					
						
							|  |  |  |         client.get_bucket_policy(Bucket=bucket_name) | 
					
						
							|  |  |  |     ex.value.response["Error"]["Code"].should.equal("NoSuchBucketPolicy") | 
					
						
							|  |  |  |     ex.value.response["Error"]["Message"].should.equal( | 
					
						
							|  |  |  |         "The bucket policy does not exist" | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     client.put_bucket_policy(Bucket=bucket_name, Policy=policy) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     client.get_bucket_policy(Bucket=bucket_name)["Policy"].should.equal(policy) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     client.delete_bucket_policy(Bucket=bucket_name) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     with pytest.raises(ClientError) as ex: | 
					
						
							|  |  |  |         client.get_bucket_policy(Bucket=bucket_name) | 
					
						
							|  |  |  |     ex.value.response["Error"]["Code"].should.equal("NoSuchBucketPolicy") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_s3 | 
					
						
							| 
									
										
										
										
											2022-02-24 20:42:38 -01:00
										 |  |  | def test_website_configuration_xml(): | 
					
						
							| 
									
										
										
										
											2021-09-21 20:06:42 +00:00
										 |  |  |     s3 = boto3.resource("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							|  |  |  |     client = boto3.client("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							|  |  |  |     bucket_name = "mybucket" | 
					
						
							|  |  |  |     bucket = s3.Bucket(bucket_name) | 
					
						
							|  |  |  |     bucket.create() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     client.put_bucket_website( | 
					
						
							|  |  |  |         Bucket=bucket_name, | 
					
						
							|  |  |  |         WebsiteConfiguration={ | 
					
						
							|  |  |  |             "IndexDocument": {"Suffix": "index.html"}, | 
					
						
							|  |  |  |             "RoutingRules": [ | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                     "Condition": {"KeyPrefixEquals": "test/testing"}, | 
					
						
							|  |  |  |                     "Redirect": {"ReplaceKeyWith": "test.txt"}, | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             ], | 
					
						
							|  |  |  |         }, | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     c = client.get_bucket_website(Bucket=bucket_name) | 
					
						
							|  |  |  |     c.should.have.key("IndexDocument").equals({"Suffix": "index.html"}) | 
					
						
							|  |  |  |     c.should.have.key("RoutingRules") | 
					
						
							|  |  |  |     c["RoutingRules"].should.have.length_of(1) | 
					
						
							|  |  |  |     rule = c["RoutingRules"][0] | 
					
						
							|  |  |  |     rule.should.have.key("Condition").equals({"KeyPrefixEquals": "test/testing"}) | 
					
						
							|  |  |  |     rule.should.have.key("Redirect").equals({"ReplaceKeyWith": "test.txt"}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     c.shouldnt.have.key("RedirectAllRequestsTo") | 
					
						
							|  |  |  |     c.shouldnt.have.key("ErrorDocument") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-20 15:42:21 -07:00
										 |  |  | @mock_s3 | 
					
						
							| 
									
										
										
										
											2022-02-24 20:42:38 -01:00
										 |  |  | def test_client_get_object_returns_etag(): | 
					
						
							| 
									
										
										
										
											2020-02-02 10:36:51 +00:00
										 |  |  |     s3 = boto3.client("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							| 
									
										
										
										
											2016-09-20 15:42:21 -07:00
										 |  |  |     s3.create_bucket(Bucket="mybucket") | 
					
						
							|  |  |  |     s3.put_object(Bucket="mybucket", Key="steve", Body=b"is awesome") | 
					
						
							|  |  |  |     resp = s3.get_object(Bucket="mybucket", Key="steve") | 
					
						
							|  |  |  |     resp["ETag"].should.equal('"d32bda93738f7e03adb22e66c90fbc04"') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-02 23:47:57 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-14 13:32:52 +02:00
										 |  |  | @mock_s3 | 
					
						
							|  |  |  | def test_website_redirect_location(): | 
					
						
							| 
									
										
										
										
											2020-02-02 10:36:51 +00:00
										 |  |  |     s3 = boto3.client("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							| 
									
										
										
										
											2017-04-14 13:32:52 +02:00
										 |  |  |     s3.create_bucket(Bucket="mybucket") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     s3.put_object(Bucket="mybucket", Key="steve", Body=b"is awesome") | 
					
						
							|  |  |  |     resp = s3.get_object(Bucket="mybucket", Key="steve") | 
					
						
							| 
									
										
										
										
											2022-04-18 20:44:56 +00:00
										 |  |  |     resp.get("WebsiteRedirectLocation").should.equal(None) | 
					
						
							| 
									
										
										
										
											2017-04-14 13:32:52 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-07 11:35:14 +00:00
										 |  |  |     url = "https://github.com/getmoto/moto" | 
					
						
							| 
									
										
										
										
											2017-04-14 13:32:52 +02:00
										 |  |  |     s3.put_object( | 
					
						
							|  |  |  |         Bucket="mybucket", Key="steve", Body=b"is awesome", WebsiteRedirectLocation=url | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     resp = s3.get_object(Bucket="mybucket", Key="steve") | 
					
						
							|  |  |  |     resp["WebsiteRedirectLocation"].should.equal(url) | 
					
						
							| 
									
										
										
										
											2017-02-23 21:37:43 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-02 23:47:57 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-21 20:51:18 +05:30
										 |  |  | @mock_s3 | 
					
						
							|  |  |  | def test_delimiter_optional_in_response(): | 
					
						
							|  |  |  |     s3 = boto3.client("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							|  |  |  |     s3.create_bucket(Bucket="mybucket") | 
					
						
							|  |  |  |     s3.put_object(Bucket="mybucket", Key="one", Body=b"1") | 
					
						
							|  |  |  |     resp = s3.list_objects(Bucket="mybucket", MaxKeys=1) | 
					
						
							|  |  |  |     assert resp.get("Delimiter") is None | 
					
						
							|  |  |  |     resp = s3.list_objects(Bucket="mybucket", MaxKeys=1, Delimiter="/") | 
					
						
							|  |  |  |     assert resp.get("Delimiter") == "/" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-14 09:49:50 +00:00
										 |  |  | @mock_s3 | 
					
						
							|  |  |  | def test_list_objects_with_pagesize_0(): | 
					
						
							|  |  |  |     s3 = boto3.client("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							|  |  |  |     s3.create_bucket(Bucket="mybucket") | 
					
						
							|  |  |  |     resp = s3.list_objects(Bucket="mybucket", MaxKeys=0) | 
					
						
							|  |  |  |     resp["Name"].should.equal("mybucket") | 
					
						
							|  |  |  |     resp["MaxKeys"].should.equal(0) | 
					
						
							|  |  |  |     resp["IsTruncated"].should.equal(False) | 
					
						
							|  |  |  |     resp.shouldnt.have.key("Contents") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-21 09:40:47 +08:00
										 |  |  | @mock_s3 | 
					
						
							| 
									
										
										
										
											2022-02-24 20:42:38 -01:00
										 |  |  | def test_list_objects_truncated_response(): | 
					
						
							| 
									
										
										
										
											2020-02-02 10:36:51 +00:00
										 |  |  |     s3 = boto3.client("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							| 
									
										
										
										
											2019-10-21 09:40:47 +08:00
										 |  |  |     s3.create_bucket(Bucket="mybucket") | 
					
						
							|  |  |  |     s3.put_object(Bucket="mybucket", Key="one", Body=b"1") | 
					
						
							|  |  |  |     s3.put_object(Bucket="mybucket", Key="two", Body=b"22") | 
					
						
							|  |  |  |     s3.put_object(Bucket="mybucket", Key="three", Body=b"333") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # First list | 
					
						
							|  |  |  |     resp = s3.list_objects(Bucket="mybucket", MaxKeys=1) | 
					
						
							|  |  |  |     listed_object = resp["Contents"][0] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     assert listed_object["Key"] == "one" | 
					
						
							|  |  |  |     assert resp["MaxKeys"] == 1 | 
					
						
							| 
									
										
										
										
											2022-03-11 20:28:45 -01:00
										 |  |  |     assert resp["IsTruncated"] is True | 
					
						
							| 
									
										
										
										
											2019-12-21 13:27:49 +01:00
										 |  |  |     assert resp.get("Prefix") is None | 
					
						
							| 
									
										
										
										
											2020-09-21 20:51:18 +05:30
										 |  |  |     assert resp.get("Delimiter") is None | 
					
						
							| 
									
										
										
										
											2019-10-21 09:40:47 +08:00
										 |  |  |     assert "NextMarker" in resp | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     next_marker = resp["NextMarker"] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Second list | 
					
						
							|  |  |  |     resp = s3.list_objects(Bucket="mybucket", MaxKeys=1, Marker=next_marker) | 
					
						
							|  |  |  |     listed_object = resp["Contents"][0] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     assert listed_object["Key"] == "three" | 
					
						
							|  |  |  |     assert resp["MaxKeys"] == 1 | 
					
						
							| 
									
										
										
										
											2022-03-11 20:28:45 -01:00
										 |  |  |     assert resp["IsTruncated"] is True | 
					
						
							| 
									
										
										
										
											2019-12-21 13:27:49 +01:00
										 |  |  |     assert resp.get("Prefix") is None | 
					
						
							| 
									
										
										
										
											2020-09-21 20:51:18 +05:30
										 |  |  |     assert resp.get("Delimiter") is None | 
					
						
							| 
									
										
										
										
											2019-10-21 09:40:47 +08:00
										 |  |  |     assert "NextMarker" in resp | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     next_marker = resp["NextMarker"] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Third list | 
					
						
							|  |  |  |     resp = s3.list_objects(Bucket="mybucket", MaxKeys=1, Marker=next_marker) | 
					
						
							|  |  |  |     listed_object = resp["Contents"][0] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     assert listed_object["Key"] == "two" | 
					
						
							|  |  |  |     assert resp["MaxKeys"] == 1 | 
					
						
							| 
									
										
										
										
											2022-03-11 20:28:45 -01:00
										 |  |  |     assert resp["IsTruncated"] is False | 
					
						
							| 
									
										
										
										
											2019-12-21 13:27:49 +01:00
										 |  |  |     assert resp.get("Prefix") is None | 
					
						
							| 
									
										
										
										
											2020-09-21 20:51:18 +05:30
										 |  |  |     assert resp.get("Delimiter") is None | 
					
						
							| 
									
										
										
										
											2019-10-21 09:40:47 +08:00
										 |  |  |     assert "NextMarker" not in resp | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-03 23:13:24 +00:00
										 |  |  | @mock_s3 | 
					
						
							| 
									
										
										
										
											2022-02-24 20:42:38 -01:00
										 |  |  | def test_list_keys_xml_escaped(): | 
					
						
							| 
									
										
										
										
											2020-02-02 10:36:51 +00:00
										 |  |  |     s3 = boto3.client("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							| 
									
										
										
										
											2016-12-03 23:13:24 +00:00
										 |  |  |     s3.create_bucket(Bucket="mybucket") | 
					
						
							|  |  |  |     key_name = "Q&A.txt" | 
					
						
							|  |  |  |     s3.put_object(Bucket="mybucket", Key=key_name, Body=b"is awesome") | 
					
						
							| 
									
										
										
										
											2017-02-09 03:21:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-03 23:13:24 +00:00
										 |  |  |     resp = s3.list_objects_v2(Bucket="mybucket", Prefix=key_name) | 
					
						
							| 
									
										
										
										
											2017-02-09 03:21:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-03 23:13:24 +00:00
										 |  |  |     assert resp["Contents"][0]["Key"] == key_name | 
					
						
							| 
									
										
										
										
											2017-02-09 03:21:43 +01:00
										 |  |  |     assert resp["KeyCount"] == 1 | 
					
						
							|  |  |  |     assert resp["MaxKeys"] == 1000 | 
					
						
							|  |  |  |     assert resp["Prefix"] == key_name | 
					
						
							| 
									
										
										
										
											2022-03-11 20:28:45 -01:00
										 |  |  |     assert resp["IsTruncated"] is False | 
					
						
							| 
									
										
										
										
											2017-02-09 03:21:43 +01:00
										 |  |  |     assert "Delimiter" not in resp | 
					
						
							|  |  |  |     assert "StartAfter" not in resp | 
					
						
							|  |  |  |     assert "NextContinuationToken" not in resp | 
					
						
							|  |  |  |     assert "Owner" not in resp["Contents"][0] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-05 16:17:28 -08:00
										 |  |  | @mock_s3 | 
					
						
							| 
									
										
										
										
											2022-02-24 20:42:38 -01:00
										 |  |  | def test_list_objects_v2_common_prefix_pagination(): | 
					
						
							| 
									
										
										
										
											2020-02-02 10:36:51 +00:00
										 |  |  |     s3 = boto3.client("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							| 
									
										
										
										
											2018-12-05 16:17:28 -08:00
										 |  |  |     s3.create_bucket(Bucket="mybucket") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     max_keys = 1 | 
					
						
							| 
									
										
										
										
											2022-11-17 21:41:08 -01:00
										 |  |  |     keys = [f"test/{i}/{i}" for i in range(3)] | 
					
						
							| 
									
										
										
										
											2018-12-05 16:17:28 -08:00
										 |  |  |     for key in keys: | 
					
						
							|  |  |  |         s3.put_object(Bucket="mybucket", Key=key, Body=b"v") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     prefixes = [] | 
					
						
							|  |  |  |     args = { | 
					
						
							|  |  |  |         "Bucket": "mybucket", | 
					
						
							|  |  |  |         "Delimiter": "/", | 
					
						
							|  |  |  |         "Prefix": "test/", | 
					
						
							|  |  |  |         "MaxKeys": max_keys, | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     resp = {"IsTruncated": True} | 
					
						
							|  |  |  |     while resp.get("IsTruncated", False): | 
					
						
							|  |  |  |         if "NextContinuationToken" in resp: | 
					
						
							|  |  |  |             args["ContinuationToken"] = resp["NextContinuationToken"] | 
					
						
							|  |  |  |         resp = s3.list_objects_v2(**args) | 
					
						
							|  |  |  |         if "CommonPrefixes" in resp: | 
					
						
							|  |  |  |             assert len(resp["CommonPrefixes"]) == max_keys | 
					
						
							|  |  |  |             prefixes.extend(i["Prefix"] for i in resp["CommonPrefixes"]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     assert prefixes == [k[: k.rindex("/") + 1] for k in keys] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-13 19:08:25 +05:30
										 |  |  | @mock_s3 | 
					
						
							| 
									
										
										
										
											2022-02-24 20:42:38 -01:00
										 |  |  | def test_list_objects_v2_common_invalid_continuation_token(): | 
					
						
							| 
									
										
										
										
											2020-12-13 19:08:25 +05:30
										 |  |  |     s3 = boto3.client("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							|  |  |  |     s3.create_bucket(Bucket="mybucket") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     max_keys = 1 | 
					
						
							| 
									
										
										
										
											2022-11-17 21:41:08 -01:00
										 |  |  |     keys = [f"test/{i}/{i}" for i in range(3)] | 
					
						
							| 
									
										
										
										
											2020-12-13 19:08:25 +05:30
										 |  |  |     for key in keys: | 
					
						
							|  |  |  |         s3.put_object(Bucket="mybucket", Key=key, Body=b"v") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     args = { | 
					
						
							|  |  |  |         "Bucket": "mybucket", | 
					
						
							|  |  |  |         "Delimiter": "/", | 
					
						
							|  |  |  |         "Prefix": "test/", | 
					
						
							|  |  |  |         "MaxKeys": max_keys, | 
					
						
							|  |  |  |         "ContinuationToken": "", | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     with pytest.raises(botocore.exceptions.ClientError) as exc: | 
					
						
							|  |  |  |         s3.list_objects_v2(**args) | 
					
						
							|  |  |  |     exc.value.response["Error"]["Code"].should.equal("InvalidArgument") | 
					
						
							|  |  |  |     exc.value.response["Error"]["Message"].should.equal( | 
					
						
							|  |  |  |         "The continuation token provided is incorrect" | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-09 03:21:43 +01:00
										 |  |  | @mock_s3 | 
					
						
							| 
									
										
										
										
											2022-02-24 20:42:38 -01:00
										 |  |  | def test_list_objects_v2_truncated_response(): | 
					
						
							| 
									
										
										
										
											2020-02-02 10:36:51 +00:00
										 |  |  |     s3 = boto3.client("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							| 
									
										
										
										
											2017-02-09 03:21:43 +01:00
										 |  |  |     s3.create_bucket(Bucket="mybucket") | 
					
						
							|  |  |  |     s3.put_object(Bucket="mybucket", Key="one", Body=b"1") | 
					
						
							|  |  |  |     s3.put_object(Bucket="mybucket", Key="two", Body=b"22") | 
					
						
							|  |  |  |     s3.put_object(Bucket="mybucket", Key="three", Body=b"333") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # First list | 
					
						
							|  |  |  |     resp = s3.list_objects_v2(Bucket="mybucket", MaxKeys=1) | 
					
						
							|  |  |  |     listed_object = resp["Contents"][0] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     assert listed_object["Key"] == "one" | 
					
						
							|  |  |  |     assert resp["MaxKeys"] == 1 | 
					
						
							|  |  |  |     assert resp["Prefix"] == "" | 
					
						
							|  |  |  |     assert resp["KeyCount"] == 1 | 
					
						
							| 
									
										
										
										
											2022-03-11 20:28:45 -01:00
										 |  |  |     assert resp["IsTruncated"] is True | 
					
						
							| 
									
										
										
										
											2017-02-09 03:21:43 +01:00
										 |  |  |     assert "Delimiter" not in resp | 
					
						
							|  |  |  |     assert "StartAfter" not in resp | 
					
						
							| 
									
										
										
										
											2017-02-23 21:37:43 -05:00
										 |  |  |     assert "Owner" not in listed_object  # owner info was not requested | 
					
						
							| 
									
										
										
										
											2017-02-09 03:21:43 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     next_token = resp["NextContinuationToken"] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Second list | 
					
						
							| 
									
										
										
										
											2017-02-23 21:37:43 -05:00
										 |  |  |     resp = s3.list_objects_v2( | 
					
						
							|  |  |  |         Bucket="mybucket", MaxKeys=1, ContinuationToken=next_token | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2017-02-09 03:21:43 +01:00
										 |  |  |     listed_object = resp["Contents"][0] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     assert listed_object["Key"] == "three" | 
					
						
							|  |  |  |     assert resp["MaxKeys"] == 1 | 
					
						
							|  |  |  |     assert resp["Prefix"] == "" | 
					
						
							|  |  |  |     assert resp["KeyCount"] == 1 | 
					
						
							| 
									
										
										
										
											2022-03-11 20:28:45 -01:00
										 |  |  |     assert resp["IsTruncated"] is True | 
					
						
							| 
									
										
										
										
											2017-02-09 03:21:43 +01:00
										 |  |  |     assert "Delimiter" not in resp | 
					
						
							|  |  |  |     assert "StartAfter" not in resp | 
					
						
							|  |  |  |     assert "Owner" not in listed_object | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     next_token = resp["NextContinuationToken"] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Third list | 
					
						
							| 
									
										
										
										
											2017-02-23 21:37:43 -05:00
										 |  |  |     resp = s3.list_objects_v2( | 
					
						
							|  |  |  |         Bucket="mybucket", MaxKeys=1, ContinuationToken=next_token | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2017-02-09 03:21:43 +01:00
										 |  |  |     listed_object = resp["Contents"][0] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     assert listed_object["Key"] == "two" | 
					
						
							|  |  |  |     assert resp["MaxKeys"] == 1 | 
					
						
							|  |  |  |     assert resp["Prefix"] == "" | 
					
						
							|  |  |  |     assert resp["KeyCount"] == 1 | 
					
						
							| 
									
										
										
										
											2022-03-11 20:28:45 -01:00
										 |  |  |     assert resp["IsTruncated"] is False | 
					
						
							| 
									
										
										
										
											2017-02-09 03:21:43 +01:00
										 |  |  |     assert "Delimiter" not in resp | 
					
						
							|  |  |  |     assert "Owner" not in listed_object | 
					
						
							|  |  |  |     assert "StartAfter" not in resp | 
					
						
							|  |  |  |     assert "NextContinuationToken" not in resp | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_s3 | 
					
						
							| 
									
										
										
										
											2022-02-24 20:42:38 -01:00
										 |  |  | def test_list_objects_v2_truncated_response_start_after(): | 
					
						
							| 
									
										
										
										
											2020-02-02 10:36:51 +00:00
										 |  |  |     s3 = boto3.client("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							| 
									
										
										
										
											2017-02-09 03:21:43 +01:00
										 |  |  |     s3.create_bucket(Bucket="mybucket") | 
					
						
							|  |  |  |     s3.put_object(Bucket="mybucket", Key="one", Body=b"1") | 
					
						
							|  |  |  |     s3.put_object(Bucket="mybucket", Key="two", Body=b"22") | 
					
						
							|  |  |  |     s3.put_object(Bucket="mybucket", Key="three", Body=b"333") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # First list | 
					
						
							|  |  |  |     resp = s3.list_objects_v2(Bucket="mybucket", MaxKeys=1, StartAfter="one") | 
					
						
							|  |  |  |     listed_object = resp["Contents"][0] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     assert listed_object["Key"] == "three" | 
					
						
							|  |  |  |     assert resp["MaxKeys"] == 1 | 
					
						
							|  |  |  |     assert resp["Prefix"] == "" | 
					
						
							|  |  |  |     assert resp["KeyCount"] == 1 | 
					
						
							| 
									
										
										
										
											2022-03-11 20:28:45 -01:00
										 |  |  |     assert resp["IsTruncated"] is True | 
					
						
							| 
									
										
										
										
											2017-02-09 03:21:43 +01:00
										 |  |  |     assert resp["StartAfter"] == "one" | 
					
						
							|  |  |  |     assert "Delimiter" not in resp | 
					
						
							|  |  |  |     assert "Owner" not in listed_object | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     next_token = resp["NextContinuationToken"] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Second list | 
					
						
							|  |  |  |     # The ContinuationToken must take precedence over StartAfter. | 
					
						
							|  |  |  |     resp = s3.list_objects_v2( | 
					
						
							|  |  |  |         Bucket="mybucket", MaxKeys=1, StartAfter="one", ContinuationToken=next_token | 
					
						
							| 
									
										
										
										
											2017-02-23 21:37:43 -05:00
										 |  |  |     ) | 
					
						
							| 
									
										
										
										
											2017-02-09 03:21:43 +01:00
										 |  |  |     listed_object = resp["Contents"][0] | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-09 03:21:43 +01:00
										 |  |  |     assert listed_object["Key"] == "two" | 
					
						
							|  |  |  |     assert resp["MaxKeys"] == 1 | 
					
						
							|  |  |  |     assert resp["Prefix"] == "" | 
					
						
							|  |  |  |     assert resp["KeyCount"] == 1 | 
					
						
							| 
									
										
										
										
											2022-03-11 20:28:45 -01:00
										 |  |  |     assert resp["IsTruncated"] is False | 
					
						
							| 
									
										
										
										
											2017-02-09 03:21:43 +01:00
										 |  |  |     # When ContinuationToken is given, StartAfter is ignored. This also means | 
					
						
							|  |  |  |     # AWS does not return it in the response. | 
					
						
							|  |  |  |     assert "StartAfter" not in resp | 
					
						
							|  |  |  |     assert "Delimiter" not in resp | 
					
						
							|  |  |  |     assert "Owner" not in listed_object | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_s3 | 
					
						
							| 
									
										
										
										
											2022-02-24 20:42:38 -01:00
										 |  |  | def test_list_objects_v2_fetch_owner(): | 
					
						
							| 
									
										
										
										
											2020-02-02 10:36:51 +00:00
										 |  |  |     s3 = boto3.client("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							| 
									
										
										
										
											2017-02-09 03:21:43 +01:00
										 |  |  |     s3.create_bucket(Bucket="mybucket") | 
					
						
							|  |  |  |     s3.put_object(Bucket="mybucket", Key="one", Body=b"11") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     resp = s3.list_objects_v2(Bucket="mybucket", FetchOwner=True) | 
					
						
							|  |  |  |     owner = resp["Contents"][0]["Owner"] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     assert "ID" in owner | 
					
						
							|  |  |  |     assert "DisplayName" in owner | 
					
						
							|  |  |  |     assert len(owner.keys()) == 2 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-20 15:42:21 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-16 16:46:19 +08:00
										 |  |  | @mock_s3 | 
					
						
							| 
									
										
										
										
											2022-02-24 20:42:38 -01:00
										 |  |  | def test_list_objects_v2_truncate_combined_keys_and_folders(): | 
					
						
							| 
									
										
										
										
											2020-02-02 10:36:51 +00:00
										 |  |  |     s3 = boto3.client("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							| 
									
										
										
										
											2019-09-16 16:46:19 +08:00
										 |  |  |     s3.create_bucket(Bucket="mybucket") | 
					
						
							| 
									
										
										
										
											2019-09-17 10:42:10 +08:00
										 |  |  |     s3.put_object(Bucket="mybucket", Key="1/2", Body="") | 
					
						
							|  |  |  |     s3.put_object(Bucket="mybucket", Key="2", Body="") | 
					
						
							|  |  |  |     s3.put_object(Bucket="mybucket", Key="3/4", Body="") | 
					
						
							|  |  |  |     s3.put_object(Bucket="mybucket", Key="4", Body="") | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-17 12:44:48 +08:00
										 |  |  |     resp = s3.list_objects_v2(Bucket="mybucket", Prefix="", MaxKeys=2, Delimiter="/") | 
					
						
							| 
									
										
										
										
											2019-09-17 10:42:10 +08:00
										 |  |  |     assert "Delimiter" in resp | 
					
						
							|  |  |  |     assert resp["IsTruncated"] is True | 
					
						
							|  |  |  |     assert resp["KeyCount"] == 2 | 
					
						
							| 
									
										
										
										
											2019-09-17 12:42:33 +08:00
										 |  |  |     assert len(resp["Contents"]) == 1 | 
					
						
							|  |  |  |     assert resp["Contents"][0]["Key"] == "2" | 
					
						
							|  |  |  |     assert len(resp["CommonPrefixes"]) == 1 | 
					
						
							|  |  |  |     assert resp["CommonPrefixes"][0]["Prefix"] == "1/" | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-17 10:42:10 +08:00
										 |  |  |     last_tail = resp["NextContinuationToken"] | 
					
						
							| 
									
										
										
										
											2019-09-17 12:44:48 +08:00
										 |  |  |     resp = s3.list_objects_v2( | 
					
						
							|  |  |  |         Bucket="mybucket", MaxKeys=2, Prefix="", Delimiter="/", StartAfter=last_tail | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2019-09-17 10:42:10 +08:00
										 |  |  |     assert resp["KeyCount"] == 2 | 
					
						
							|  |  |  |     assert resp["IsTruncated"] is False | 
					
						
							| 
									
										
										
										
											2019-09-17 12:42:33 +08:00
										 |  |  |     assert len(resp["Contents"]) == 1 | 
					
						
							|  |  |  |     assert resp["Contents"][0]["Key"] == "4" | 
					
						
							|  |  |  |     assert len(resp["CommonPrefixes"]) == 1 | 
					
						
							|  |  |  |     assert resp["CommonPrefixes"][0]["Prefix"] == "3/" | 
					
						
							| 
									
										
										
										
											2019-09-16 16:46:19 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-06 22:03:28 -01:00
										 |  |  | @mock_s3 | 
					
						
							|  |  |  | def test_list_objects_v2_checksum_algo(): | 
					
						
							|  |  |  |     s3 = boto3.client("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							|  |  |  |     s3.create_bucket(Bucket="mybucket") | 
					
						
							| 
									
										
										
										
											2022-12-14 16:36:35 +05:30
										 |  |  |     resp = s3.put_object(Bucket="mybucket", Key="0", Body="a") | 
					
						
							|  |  |  |     resp.should_not.have.key("ChecksumCRC32") | 
					
						
							|  |  |  |     resp["ResponseMetadata"]["HTTPHeaders"].should_not.have.key( | 
					
						
							|  |  |  |         "x-amz-sdk-checksum-algorithm" | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2022-12-06 22:03:28 -01:00
										 |  |  |     resp = s3.put_object( | 
					
						
							|  |  |  |         Bucket="mybucket", Key="1", Body="a", ChecksumAlgorithm="CRC32" | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     resp.should.have.key("ChecksumCRC32") | 
					
						
							|  |  |  |     resp["ResponseMetadata"]["HTTPHeaders"][ | 
					
						
							|  |  |  |         "x-amz-sdk-checksum-algorithm" | 
					
						
							|  |  |  |     ].should.equal("CRC32") | 
					
						
							|  |  |  |     resp = s3.put_object( | 
					
						
							|  |  |  |         Bucket="mybucket", Key="2", Body="b", ChecksumAlgorithm="SHA256" | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     resp.should.have.key("ChecksumSHA256") | 
					
						
							|  |  |  |     resp["ResponseMetadata"]["HTTPHeaders"][ | 
					
						
							|  |  |  |         "x-amz-sdk-checksum-algorithm" | 
					
						
							|  |  |  |     ].should.equal("SHA256") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     resp = s3.list_objects_v2(Bucket="mybucket")["Contents"] | 
					
						
							| 
									
										
										
										
											2022-12-14 16:36:35 +05:30
										 |  |  |     resp[0].should_not.have.key("ChecksumAlgorithm") | 
					
						
							|  |  |  |     resp[1].should.have.key("ChecksumAlgorithm").equals(["CRC32"]) | 
					
						
							|  |  |  |     resp[2].should.have.key("ChecksumAlgorithm").equals(["SHA256"]) | 
					
						
							| 
									
										
										
										
											2022-12-06 22:03:28 -01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-02 09:54:23 -04:00
										 |  |  | @mock_s3 | 
					
						
							| 
									
										
										
										
											2022-02-24 20:42:38 -01:00
										 |  |  | def test_bucket_create(): | 
					
						
							| 
									
										
										
										
											2020-02-02 10:36:51 +00:00
										 |  |  |     s3 = boto3.resource("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							| 
									
										
										
										
											2015-08-02 09:54:23 -04:00
										 |  |  |     s3.create_bucket(Bucket="blah") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     s3.Object("blah", "hello.txt").put(Body="some text") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-23 21:37:43 -05:00
										 |  |  |     s3.Object("blah", "hello.txt").get()["Body"].read().decode("utf-8").should.equal( | 
					
						
							|  |  |  |         "some text" | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2015-08-13 21:16:55 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-20 18:39:31 +01:00
										 |  |  | @mock_s3 | 
					
						
							|  |  |  | def test_bucket_create_force_us_east_1(): | 
					
						
							| 
									
										
										
										
											2020-02-02 10:36:51 +00:00
										 |  |  |     s3 = boto3.resource("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							| 
									
										
										
										
											2020-10-06 07:54:49 +02:00
										 |  |  |     with pytest.raises(ClientError) as exc: | 
					
						
							| 
									
										
										
										
											2018-11-20 18:39:31 +01:00
										 |  |  |         s3.create_bucket( | 
					
						
							| 
									
										
										
										
											2020-02-02 11:48:32 +00:00
										 |  |  |             Bucket="blah", | 
					
						
							|  |  |  |             CreateBucketConfiguration={"LocationConstraint": DEFAULT_REGION_NAME}, | 
					
						
							| 
									
										
										
										
											2018-11-20 18:39:31 +01:00
										 |  |  |         ) | 
					
						
							| 
									
										
										
										
											2020-10-06 08:04:09 +02:00
										 |  |  |     exc.value.response["Error"]["Code"].should.equal("InvalidLocationConstraint") | 
					
						
							| 
									
										
										
										
											2018-11-20 18:39:31 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-27 14:43:03 -05:00
										 |  |  | @mock_s3 | 
					
						
							| 
									
										
										
										
											2022-02-24 20:42:38 -01:00
										 |  |  | def test_bucket_create_eu_central(): | 
					
						
							| 
									
										
										
										
											2015-11-27 14:43:03 -05:00
										 |  |  |     s3 = boto3.resource("s3", region_name="eu-central-1") | 
					
						
							| 
									
										
										
										
											2020-02-02 10:36:51 +00:00
										 |  |  |     s3.create_bucket( | 
					
						
							|  |  |  |         Bucket="blah", CreateBucketConfiguration={"LocationConstraint": "eu-central-1"} | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2015-11-27 14:43:03 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     s3.Object("blah", "hello.txt").put(Body="some text") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-23 21:37:43 -05:00
										 |  |  |     s3.Object("blah", "hello.txt").get()["Body"].read().decode("utf-8").should.equal( | 
					
						
							|  |  |  |         "some text" | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2015-11-27 14:43:03 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-19 11:44:43 +01:00
										 |  |  | @mock_s3 | 
					
						
							|  |  |  | def test_bucket_create_empty_bucket_configuration_should_return_malformed_xml_error(): | 
					
						
							|  |  |  |     s3 = boto3.resource("s3", region_name="us-east-1") | 
					
						
							| 
									
										
										
										
											2020-10-06 07:54:49 +02:00
										 |  |  |     with pytest.raises(ClientError) as e: | 
					
						
							| 
									
										
										
										
											2020-06-19 11:44:43 +01:00
										 |  |  |         s3.create_bucket(Bucket="whatever", CreateBucketConfiguration={}) | 
					
						
							| 
									
										
										
										
											2020-10-06 08:04:09 +02:00
										 |  |  |     e.value.response["Error"]["Code"].should.equal("MalformedXML") | 
					
						
							|  |  |  |     e.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400) | 
					
						
							| 
									
										
										
										
											2020-06-19 11:44:43 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-13 21:16:55 +00:00
										 |  |  | @mock_s3 | 
					
						
							| 
									
										
										
										
											2022-02-24 20:42:38 -01:00
										 |  |  | def test_head_object(): | 
					
						
							| 
									
										
										
										
											2020-02-02 10:36:51 +00:00
										 |  |  |     s3 = boto3.resource("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							| 
									
										
										
										
											2015-08-13 21:16:55 +00:00
										 |  |  |     s3.create_bucket(Bucket="blah") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     s3.Object("blah", "hello.txt").put(Body="some text") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-23 21:37:43 -05:00
										 |  |  |     s3.Object("blah", "hello.txt").meta.client.head_object( | 
					
						
							|  |  |  |         Bucket="blah", Key="hello.txt" | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2015-08-13 21:16:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-06 07:54:49 +02:00
										 |  |  |     with pytest.raises(ClientError) as e: | 
					
						
							| 
									
										
										
										
											2017-02-23 21:37:43 -05:00
										 |  |  |         s3.Object("blah", "hello2.txt").meta.client.head_object( | 
					
						
							|  |  |  |             Bucket="blah", Key="hello_bad.txt" | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2020-10-06 08:04:09 +02:00
										 |  |  |     e.value.response["Error"]["Code"].should.equal("404") | 
					
						
							| 
									
										
										
										
											2015-11-04 18:55:41 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-19 17:18:31 -07:00
										 |  |  | @mock_s3 | 
					
						
							| 
									
										
										
										
											2022-02-24 20:42:38 -01:00
										 |  |  | def test_get_object(): | 
					
						
							| 
									
										
										
										
											2020-02-02 10:36:51 +00:00
										 |  |  |     s3 = boto3.resource("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							| 
									
										
										
										
											2016-07-08 19:32:34 +00:00
										 |  |  |     s3.create_bucket(Bucket="blah") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     s3.Object("blah", "hello.txt").put(Body="some text") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-23 21:37:43 -05:00
										 |  |  |     s3.Object("blah", "hello.txt").meta.client.head_object( | 
					
						
							|  |  |  |         Bucket="blah", Key="hello.txt" | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2016-07-08 19:32:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-06 07:54:49 +02:00
										 |  |  |     with pytest.raises(ClientError) as e: | 
					
						
							| 
									
										
										
										
											2016-07-08 19:32:34 +00:00
										 |  |  |         s3.Object("blah", "hello2.txt").get() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-06 08:04:09 +02:00
										 |  |  |     e.value.response["Error"]["Code"].should.equal("NoSuchKey") | 
					
						
							| 
									
										
										
										
											2016-07-08 19:32:34 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-10 12:56:33 +00:00
										 |  |  | @mock_s3 | 
					
						
							| 
									
										
										
										
											2022-02-24 20:42:38 -01:00
										 |  |  | def test_s3_content_type(): | 
					
						
							| 
									
										
										
										
											2020-03-10 12:56:33 +00:00
										 |  |  |     s3 = boto3.resource("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							|  |  |  |     my_bucket = s3.Bucket("my-cool-bucket") | 
					
						
							|  |  |  |     my_bucket.create() | 
					
						
							| 
									
										
										
										
											2020-03-10 13:30:38 +00:00
										 |  |  |     s3_path = "test_s3.py" | 
					
						
							| 
									
										
										
										
											2020-03-10 12:56:33 +00:00
										 |  |  |     s3 = boto3.resource("s3", verify=False) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-10 13:30:38 +00:00
										 |  |  |     content_type = "text/python-x" | 
					
						
							|  |  |  |     s3.Object(my_bucket.name, s3_path).put( | 
					
						
							| 
									
										
										
										
											2021-10-12 17:50:36 +00:00
										 |  |  |         ContentType=content_type, Body=b"some python code" | 
					
						
							| 
									
										
										
										
											2020-03-10 13:30:38 +00:00
										 |  |  |     ) | 
					
						
							| 
									
										
										
										
											2020-03-10 12:56:33 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-10 13:30:38 +00:00
										 |  |  |     s3.Object(my_bucket.name, s3_path).content_type.should.equal(content_type) | 
					
						
							| 
									
										
										
										
											2020-03-10 12:56:33 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-16 18:13:59 +09:00
										 |  |  | @mock_s3 | 
					
						
							| 
									
										
										
										
											2022-02-24 20:42:38 -01:00
										 |  |  | def test_get_missing_object_with_part_number(): | 
					
						
							| 
									
										
										
										
											2020-02-02 10:36:51 +00:00
										 |  |  |     s3 = boto3.resource("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							| 
									
										
										
										
											2019-10-16 18:13:59 +09:00
										 |  |  |     s3.create_bucket(Bucket="blah") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-06 07:54:49 +02:00
										 |  |  |     with pytest.raises(ClientError) as e: | 
					
						
							| 
									
										
										
										
											2019-10-16 18:13:59 +09:00
										 |  |  |         s3.Object("blah", "hello.txt").meta.client.head_object( | 
					
						
							|  |  |  |             Bucket="blah", Key="hello.txt", PartNumber=123 | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-06 08:04:09 +02:00
										 |  |  |     e.value.response["Error"]["Code"].should.equal("404") | 
					
						
							| 
									
										
										
										
											2019-10-16 18:13:59 +09:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-28 13:17:33 -07:00
										 |  |  | @mock_s3 | 
					
						
							| 
									
										
										
										
											2022-02-24 20:42:38 -01:00
										 |  |  | def test_head_object_with_versioning(): | 
					
						
							| 
									
										
										
										
											2020-02-02 10:36:51 +00:00
										 |  |  |     s3 = boto3.resource("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							| 
									
										
										
										
											2016-04-28 13:17:33 -07:00
										 |  |  |     bucket = s3.create_bucket(Bucket="blah") | 
					
						
							|  |  |  |     bucket.Versioning().enable() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     old_content = "some text" | 
					
						
							|  |  |  |     new_content = "some new text" | 
					
						
							|  |  |  |     s3.Object("blah", "hello.txt").put(Body=old_content) | 
					
						
							|  |  |  |     s3.Object("blah", "hello.txt").put(Body=new_content) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-08 22:01:27 +01:00
										 |  |  |     versions = list(s3.Bucket("blah").object_versions.all()) | 
					
						
							|  |  |  |     latest = list(filter(lambda item: item.is_latest, versions))[0] | 
					
						
							|  |  |  |     oldest = list(filter(lambda item: not item.is_latest, versions))[0] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-28 13:17:33 -07:00
										 |  |  |     head_object = s3.Object("blah", "hello.txt").meta.client.head_object( | 
					
						
							|  |  |  |         Bucket="blah", Key="hello.txt" | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2019-03-08 22:01:27 +01:00
										 |  |  |     head_object["VersionId"].should.equal(latest.id) | 
					
						
							| 
									
										
										
										
											2016-04-28 13:17:33 -07:00
										 |  |  |     head_object["ContentLength"].should.equal(len(new_content)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     old_head_object = s3.Object("blah", "hello.txt").meta.client.head_object( | 
					
						
							| 
									
										
										
										
											2019-03-08 22:01:27 +01:00
										 |  |  |         Bucket="blah", Key="hello.txt", VersionId=oldest.id | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     old_head_object["VersionId"].should.equal(oldest.id) | 
					
						
							| 
									
										
										
										
											2016-04-28 13:17:33 -07:00
										 |  |  |     old_head_object["ContentLength"].should.equal(len(old_content)) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-08 22:01:27 +01:00
										 |  |  |     old_head_object["VersionId"].should_not.equal(head_object["VersionId"]) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-28 13:17:33 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-14 16:16:58 -01:00
										 |  |  | @mock_s3 | 
					
						
							| 
									
										
										
										
											2022-02-24 20:42:38 -01:00
										 |  |  | def test_deleted_versionings_list(): | 
					
						
							| 
									
										
										
										
											2020-02-02 10:36:51 +00:00
										 |  |  |     client = boto3.client("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							| 
									
										
										
										
											2017-10-19 00:22:35 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-24 20:42:38 -01:00
										 |  |  |     client.create_bucket(Bucket="blah") | 
					
						
							| 
									
										
										
										
											2017-10-19 00:22:35 +01:00
										 |  |  |     client.put_bucket_versioning( | 
					
						
							|  |  |  |         Bucket="blah", VersioningConfiguration={"Status": "Enabled"} | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     client.put_object(Bucket="blah", Key="test1", Body=b"test1") | 
					
						
							|  |  |  |     client.put_object(Bucket="blah", Key="test2", Body=b"test2") | 
					
						
							| 
									
										
										
										
											2022-02-24 20:42:38 -01:00
										 |  |  |     client.delete_objects(Bucket="blah", Delete={"Objects": [{"Key": "test1"}]}) | 
					
						
							| 
									
										
										
										
											2017-10-19 00:22:35 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-24 20:42:38 -01:00
										 |  |  |     listed = client.list_objects_v2(Bucket="blah") | 
					
						
							|  |  |  |     assert len(listed["Contents"]) == 1 | 
					
						
							| 
									
										
										
										
											2017-10-19 00:22:35 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-24 20:42:38 -01:00
										 |  |  | @mock_s3 | 
					
						
							|  |  |  | def test_delete_objects_for_specific_version_id(): | 
					
						
							|  |  |  |     client = boto3.client("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							|  |  |  |     client.create_bucket(Bucket="blah") | 
					
						
							|  |  |  |     client.put_bucket_versioning( | 
					
						
							|  |  |  |         Bucket="blah", VersioningConfiguration={"Status": "Enabled"} | 
					
						
							| 
									
										
										
										
											2020-04-22 19:31:43 +02:00
										 |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     client.put_object(Bucket="blah", Key="test1", Body=b"test1a") | 
					
						
							|  |  |  |     client.put_object(Bucket="blah", Key="test1", Body=b"test1b") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     response = client.list_object_versions(Bucket="blah", Prefix="test1") | 
					
						
							|  |  |  |     id_to_delete = [v["VersionId"] for v in response["Versions"] if v["IsLatest"]][0] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     response = client.delete_objects( | 
					
						
							|  |  |  |         Bucket="blah", Delete={"Objects": [{"Key": "test1", "VersionId": id_to_delete}]} | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     assert response["Deleted"] == [{"Key": "test1", "VersionId": id_to_delete}] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     listed = client.list_objects_v2(Bucket="blah") | 
					
						
							|  |  |  |     assert len(listed["Contents"]) == 1 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-03 02:30:29 -07:00
										 |  |  | @mock_s3 | 
					
						
							| 
									
										
										
										
											2022-02-24 20:42:38 -01:00
										 |  |  | def test_delete_versioned_bucket(): | 
					
						
							| 
									
										
										
										
											2020-02-02 10:36:51 +00:00
										 |  |  |     client = boto3.client("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							| 
									
										
										
										
											2018-05-03 02:30:29 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     client.create_bucket(Bucket="blah") | 
					
						
							|  |  |  |     client.put_bucket_versioning( | 
					
						
							|  |  |  |         Bucket="blah", VersioningConfiguration={"Status": "Enabled"} | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     resp = client.put_object(Bucket="blah", Key="test1", Body=b"test1") | 
					
						
							|  |  |  |     client.delete_object(Bucket="blah", Key="test1", VersionId=resp["VersionId"]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     client.delete_bucket(Bucket="blah") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-23 17:16:20 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-15 14:29:09 +02:00
										 |  |  | @mock_s3 | 
					
						
							| 
									
										
										
										
											2022-02-24 20:42:38 -01:00
										 |  |  | def test_delete_versioned_bucket_returns_meta(): | 
					
						
							| 
									
										
										
										
											2020-09-15 14:29:09 +02:00
										 |  |  |     client = boto3.client("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     client.create_bucket(Bucket="blah") | 
					
						
							|  |  |  |     client.put_bucket_versioning( | 
					
						
							|  |  |  |         Bucket="blah", VersioningConfiguration={"Status": "Enabled"} | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-18 19:44:29 +00:00
										 |  |  |     client.put_object(Bucket="blah", Key="test1", Body=b"test1") | 
					
						
							| 
									
										
										
										
											2020-09-15 14:29:09 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # Delete the object | 
					
						
							|  |  |  |     del_resp = client.delete_object(Bucket="blah", Key="test1") | 
					
						
							|  |  |  |     assert "DeleteMarker" not in del_resp | 
					
						
							|  |  |  |     assert del_resp["VersionId"] is not None | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Delete the delete marker | 
					
						
							|  |  |  |     del_resp2 = client.delete_object( | 
					
						
							|  |  |  |         Bucket="blah", Key="test1", VersionId=del_resp["VersionId"] | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2022-03-11 20:28:45 -01:00
										 |  |  |     assert del_resp2["DeleteMarker"] is True | 
					
						
							| 
									
										
										
										
											2020-09-15 14:29:09 +02:00
										 |  |  |     assert "VersionId" not in del_resp2 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-16 22:12:48 +01:00
										 |  |  | @mock_s3 | 
					
						
							|  |  |  | def test_get_object_if_modified_since_refresh(): | 
					
						
							|  |  |  |     s3 = boto3.client("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							|  |  |  |     bucket_name = "blah" | 
					
						
							|  |  |  |     s3.create_bucket(Bucket=bucket_name) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     key = "hello.txt" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     s3.put_object(Bucket=bucket_name, Key=key, Body="test") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     response = s3.get_object(Bucket=bucket_name, Key=key) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     with pytest.raises(botocore.exceptions.ClientError) as err: | 
					
						
							|  |  |  |         s3.get_object( | 
					
						
							|  |  |  |             Bucket=bucket_name, | 
					
						
							|  |  |  |             Key=key, | 
					
						
							|  |  |  |             IfModifiedSince=response["LastModified"], | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |     e = err.value | 
					
						
							|  |  |  |     e.response["Error"].should.equal({"Code": "304", "Message": "Not Modified"}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-03 11:35:56 -04:00
										 |  |  | @mock_s3 | 
					
						
							| 
									
										
										
										
											2022-02-24 20:42:38 -01:00
										 |  |  | def test_get_object_if_modified_since(): | 
					
						
							| 
									
										
										
										
											2020-02-02 10:36:51 +00:00
										 |  |  |     s3 = boto3.client("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							| 
									
										
										
										
											2019-07-03 11:35:56 -04:00
										 |  |  |     bucket_name = "blah" | 
					
						
							|  |  |  |     s3.create_bucket(Bucket=bucket_name) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     key = "hello.txt" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     s3.put_object(Bucket=bucket_name, Key=key, Body="test") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-06 07:54:49 +02:00
										 |  |  |     with pytest.raises(botocore.exceptions.ClientError) as err: | 
					
						
							| 
									
										
										
										
											2019-07-03 11:35:56 -04:00
										 |  |  |         s3.get_object( | 
					
						
							|  |  |  |             Bucket=bucket_name, | 
					
						
							|  |  |  |             Key=key, | 
					
						
							|  |  |  |             IfModifiedSince=datetime.datetime.utcnow() + datetime.timedelta(hours=1), | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2020-10-06 08:04:09 +02:00
										 |  |  |     e = err.value | 
					
						
							| 
									
										
										
										
											2019-07-03 11:35:56 -04:00
										 |  |  |     e.response["Error"].should.equal({"Code": "304", "Message": "Not Modified"}) | 
					
						
							| 
									
										
										
										
											2018-05-03 02:30:29 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-23 17:16:20 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-11 05:17:39 -04:00
										 |  |  | @mock_s3 | 
					
						
							| 
									
										
										
										
											2022-02-24 20:42:38 -01:00
										 |  |  | def test_get_object_if_unmodified_since(): | 
					
						
							| 
									
										
										
										
											2020-09-11 05:17:39 -04:00
										 |  |  |     s3 = boto3.client("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							|  |  |  |     bucket_name = "blah" | 
					
						
							|  |  |  |     s3.create_bucket(Bucket=bucket_name) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     key = "hello.txt" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     s3.put_object(Bucket=bucket_name, Key=key, Body="test") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-06 08:04:09 +02:00
										 |  |  |     with pytest.raises(botocore.exceptions.ClientError) as err: | 
					
						
							| 
									
										
										
										
											2020-09-11 05:17:39 -04:00
										 |  |  |         s3.get_object( | 
					
						
							|  |  |  |             Bucket=bucket_name, | 
					
						
							|  |  |  |             Key=key, | 
					
						
							|  |  |  |             IfUnmodifiedSince=datetime.datetime.utcnow() - datetime.timedelta(hours=1), | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2020-10-06 08:04:09 +02:00
										 |  |  |     e = err.value | 
					
						
							| 
									
										
										
										
											2020-09-11 05:17:39 -04:00
										 |  |  |     e.response["Error"]["Code"].should.equal("PreconditionFailed") | 
					
						
							|  |  |  |     e.response["Error"]["Condition"].should.equal("If-Unmodified-Since") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_s3 | 
					
						
							| 
									
										
										
										
											2022-02-24 20:42:38 -01:00
										 |  |  | def test_get_object_if_match(): | 
					
						
							| 
									
										
										
										
											2020-09-11 05:17:39 -04:00
										 |  |  |     s3 = boto3.client("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							|  |  |  |     bucket_name = "blah" | 
					
						
							|  |  |  |     s3.create_bucket(Bucket=bucket_name) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     key = "hello.txt" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     s3.put_object(Bucket=bucket_name, Key=key, Body="test") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-06 08:04:09 +02:00
										 |  |  |     with pytest.raises(botocore.exceptions.ClientError) as err: | 
					
						
							| 
									
										
										
										
											2020-11-11 15:55:37 +00:00
										 |  |  |         s3.get_object(Bucket=bucket_name, Key=key, IfMatch='"hello"') | 
					
						
							| 
									
										
										
										
											2020-10-06 08:04:09 +02:00
										 |  |  |     e = err.value | 
					
						
							| 
									
										
										
										
											2020-09-11 05:17:39 -04:00
										 |  |  |     e.response["Error"]["Code"].should.equal("PreconditionFailed") | 
					
						
							|  |  |  |     e.response["Error"]["Condition"].should.equal("If-Match") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_s3 | 
					
						
							| 
									
										
										
										
											2022-02-24 20:42:38 -01:00
										 |  |  | def test_get_object_if_none_match(): | 
					
						
							| 
									
										
										
										
											2020-09-11 05:17:39 -04:00
										 |  |  |     s3 = boto3.client("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							|  |  |  |     bucket_name = "blah" | 
					
						
							|  |  |  |     s3.create_bucket(Bucket=bucket_name) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     key = "hello.txt" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     etag = s3.put_object(Bucket=bucket_name, Key=key, Body="test")["ETag"] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-06 08:04:09 +02:00
										 |  |  |     with pytest.raises(botocore.exceptions.ClientError) as err: | 
					
						
							| 
									
										
										
										
											2020-11-11 15:55:37 +00:00
										 |  |  |         s3.get_object(Bucket=bucket_name, Key=key, IfNoneMatch=etag) | 
					
						
							| 
									
										
										
										
											2020-10-06 08:04:09 +02:00
										 |  |  |     e = err.value | 
					
						
							| 
									
										
										
										
											2020-09-11 05:17:39 -04:00
										 |  |  |     e.response["Error"].should.equal({"Code": "304", "Message": "Not Modified"}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-19 15:59:25 -07:00
										 |  |  | @mock_s3 | 
					
						
							| 
									
										
										
										
											2022-02-24 20:42:38 -01:00
										 |  |  | def test_head_object_if_modified_since(): | 
					
						
							| 
									
										
										
										
											2020-02-02 10:36:51 +00:00
										 |  |  |     s3 = boto3.client("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							| 
									
										
										
										
											2017-05-19 15:59:25 -07:00
										 |  |  |     bucket_name = "blah" | 
					
						
							|  |  |  |     s3.create_bucket(Bucket=bucket_name) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     key = "hello.txt" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-23 11:29:01 -07:00
										 |  |  |     s3.put_object(Bucket=bucket_name, Key=key, Body="test") | 
					
						
							| 
									
										
										
										
											2017-05-19 15:59:25 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-06 07:54:49 +02:00
										 |  |  |     with pytest.raises(botocore.exceptions.ClientError) as err: | 
					
						
							| 
									
										
										
										
											2017-05-19 15:59:25 -07:00
										 |  |  |         s3.head_object( | 
					
						
							|  |  |  |             Bucket=bucket_name, | 
					
						
							|  |  |  |             Key=key, | 
					
						
							| 
									
										
										
										
											2017-05-23 11:29:01 -07:00
										 |  |  |             IfModifiedSince=datetime.datetime.utcnow() + datetime.timedelta(hours=1), | 
					
						
							| 
									
										
										
										
											2017-05-19 15:59:25 -07:00
										 |  |  |         ) | 
					
						
							| 
									
										
										
										
											2020-10-06 08:04:09 +02:00
										 |  |  |     e = err.value | 
					
						
							| 
									
										
										
										
											2017-05-19 15:59:25 -07:00
										 |  |  |     e.response["Error"].should.equal({"Code": "304", "Message": "Not Modified"}) | 
					
						
							| 
									
										
										
										
											2022-11-16 22:12:48 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_s3 | 
					
						
							|  |  |  | def test_head_object_if_modified_since_refresh(): | 
					
						
							|  |  |  |     s3 = boto3.client("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							|  |  |  |     bucket_name = "blah" | 
					
						
							|  |  |  |     s3.create_bucket(Bucket=bucket_name) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     key = "hello.txt" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     s3.put_object(Bucket=bucket_name, Key=key, Body="test") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     response = s3.head_object(Bucket=bucket_name, Key=key) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     with pytest.raises(botocore.exceptions.ClientError) as err: | 
					
						
							|  |  |  |         s3.head_object( | 
					
						
							|  |  |  |             Bucket=bucket_name, | 
					
						
							|  |  |  |             Key=key, | 
					
						
							|  |  |  |             IfModifiedSince=response["LastModified"], | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |     e = err.value | 
					
						
							|  |  |  |     e.response["Error"].should.equal({"Code": "304", "Message": "Not Modified"}) | 
					
						
							| 
									
										
										
										
											2017-05-19 15:59:25 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-11 05:17:39 -04:00
										 |  |  | @mock_s3 | 
					
						
							| 
									
										
										
										
											2022-02-24 20:42:38 -01:00
										 |  |  | def test_head_object_if_unmodified_since(): | 
					
						
							| 
									
										
										
										
											2020-09-11 05:17:39 -04:00
										 |  |  |     s3 = boto3.client("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							|  |  |  |     bucket_name = "blah" | 
					
						
							|  |  |  |     s3.create_bucket(Bucket=bucket_name) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     key = "hello.txt" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     s3.put_object(Bucket=bucket_name, Key=key, Body="test") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-06 08:04:09 +02:00
										 |  |  |     with pytest.raises(botocore.exceptions.ClientError) as err: | 
					
						
							| 
									
										
										
										
											2020-09-11 05:17:39 -04:00
										 |  |  |         s3.head_object( | 
					
						
							|  |  |  |             Bucket=bucket_name, | 
					
						
							|  |  |  |             Key=key, | 
					
						
							|  |  |  |             IfUnmodifiedSince=datetime.datetime.utcnow() - datetime.timedelta(hours=1), | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2020-10-06 08:04:09 +02:00
										 |  |  |     e = err.value | 
					
						
							| 
									
										
										
										
											2020-09-11 05:17:39 -04:00
										 |  |  |     e.response["Error"].should.equal({"Code": "412", "Message": "Precondition Failed"}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_s3 | 
					
						
							| 
									
										
										
										
											2022-02-24 20:42:38 -01:00
										 |  |  | def test_head_object_if_match(): | 
					
						
							| 
									
										
										
										
											2020-09-11 05:17:39 -04:00
										 |  |  |     s3 = boto3.client("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							|  |  |  |     bucket_name = "blah" | 
					
						
							|  |  |  |     s3.create_bucket(Bucket=bucket_name) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     key = "hello.txt" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     s3.put_object(Bucket=bucket_name, Key=key, Body="test") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-06 08:04:09 +02:00
										 |  |  |     with pytest.raises(botocore.exceptions.ClientError) as err: | 
					
						
							| 
									
										
										
										
											2020-11-11 15:55:37 +00:00
										 |  |  |         s3.head_object(Bucket=bucket_name, Key=key, IfMatch='"hello"') | 
					
						
							| 
									
										
										
										
											2020-10-06 08:04:09 +02:00
										 |  |  |     e = err.value | 
					
						
							| 
									
										
										
										
											2020-09-11 05:17:39 -04:00
										 |  |  |     e.response["Error"].should.equal({"Code": "412", "Message": "Precondition Failed"}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_s3 | 
					
						
							| 
									
										
										
										
											2022-02-24 20:42:38 -01:00
										 |  |  | def test_head_object_if_none_match(): | 
					
						
							| 
									
										
										
										
											2020-09-11 05:17:39 -04:00
										 |  |  |     s3 = boto3.client("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							|  |  |  |     bucket_name = "blah" | 
					
						
							|  |  |  |     s3.create_bucket(Bucket=bucket_name) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     key = "hello.txt" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     etag = s3.put_object(Bucket=bucket_name, Key=key, Body="test")["ETag"] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-06 08:04:09 +02:00
										 |  |  |     with pytest.raises(botocore.exceptions.ClientError) as err: | 
					
						
							| 
									
										
										
										
											2020-11-11 15:55:37 +00:00
										 |  |  |         s3.head_object(Bucket=bucket_name, Key=key, IfNoneMatch=etag) | 
					
						
							| 
									
										
										
										
											2020-10-06 08:04:09 +02:00
										 |  |  |     e = err.value | 
					
						
							| 
									
										
										
										
											2020-09-11 05:17:39 -04:00
										 |  |  |     e.response["Error"].should.equal({"Code": "304", "Message": "Not Modified"}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-20 15:42:21 -07:00
										 |  |  | @mock_s3 | 
					
						
							| 
									
										
										
										
											2022-02-24 20:42:38 -01:00
										 |  |  | def test_put_bucket_cors(): | 
					
						
							| 
									
										
										
										
											2020-02-02 10:36:51 +00:00
										 |  |  |     s3 = boto3.client("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							| 
									
										
										
										
											2017-09-07 11:30:05 -07:00
										 |  |  |     bucket_name = "mybucket" | 
					
						
							|  |  |  |     s3.create_bucket(Bucket=bucket_name) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     resp = s3.put_bucket_cors( | 
					
						
							|  |  |  |         Bucket=bucket_name, | 
					
						
							|  |  |  |         CORSConfiguration={ | 
					
						
							|  |  |  |             "CORSRules": [ | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                     "AllowedOrigins": ["*"], | 
					
						
							|  |  |  |                     "AllowedMethods": ["GET", "POST"], | 
					
						
							|  |  |  |                     "AllowedHeaders": ["Authorization"], | 
					
						
							|  |  |  |                     "ExposeHeaders": ["x-amz-request-id"], | 
					
						
							|  |  |  |                     "MaxAgeSeconds": 123, | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |                 }, | 
					
						
							|  |  |  |                 { | 
					
						
							| 
									
										
										
										
											2017-09-07 11:30:05 -07:00
										 |  |  |                     "AllowedOrigins": ["*"], | 
					
						
							|  |  |  |                     "AllowedMethods": ["PUT"], | 
					
						
							|  |  |  |                     "AllowedHeaders": ["Authorization"], | 
					
						
							|  |  |  |                     "ExposeHeaders": ["x-amz-request-id"], | 
					
						
							|  |  |  |                     "MaxAgeSeconds": 123, | 
					
						
							|  |  |  |                 }, | 
					
						
							|  |  |  |             ] | 
					
						
							|  |  |  |         }, | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-07 11:30:05 -07:00
										 |  |  |     resp["ResponseMetadata"]["HTTPStatusCode"].should.equal(200) | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-06 07:54:49 +02:00
										 |  |  |     with pytest.raises(ClientError) as err: | 
					
						
							| 
									
										
										
										
											2017-09-07 11:30:05 -07:00
										 |  |  |         s3.put_bucket_cors( | 
					
						
							| 
									
										
										
										
											2017-05-19 15:59:25 -07:00
										 |  |  |             Bucket=bucket_name, | 
					
						
							| 
									
										
										
										
											2017-09-07 11:30:05 -07:00
										 |  |  |             CORSConfiguration={ | 
					
						
							|  |  |  |                 "CORSRules": [ | 
					
						
							|  |  |  |                     {"AllowedOrigins": ["*"], "AllowedMethods": ["NOTREAL", "POST"]} | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |                 ] | 
					
						
							|  |  |  |             }, | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2020-10-06 08:04:09 +02:00
										 |  |  |     e = err.value | 
					
						
							| 
									
										
										
										
											2017-09-07 11:30:05 -07:00
										 |  |  |     e.response["Error"]["Code"].should.equal("InvalidRequest") | 
					
						
							| 
									
										
										
										
											2018-01-02 23:47:57 -05:00
										 |  |  |     e.response["Error"]["Message"].should.equal( | 
					
						
							|  |  |  |         "Found unsupported HTTP method in CORS config. " "Unsupported method is NOTREAL" | 
					
						
							| 
									
										
										
										
											2017-09-07 11:30:05 -07:00
										 |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-06 07:54:49 +02:00
										 |  |  |     with pytest.raises(ClientError) as err: | 
					
						
							| 
									
										
										
										
											2017-09-07 11:30:05 -07:00
										 |  |  |         s3.put_bucket_cors(Bucket=bucket_name, CORSConfiguration={"CORSRules": []}) | 
					
						
							| 
									
										
										
										
											2020-10-06 08:04:09 +02:00
										 |  |  |     e = err.value | 
					
						
							| 
									
										
										
										
											2017-09-07 11:30:05 -07:00
										 |  |  |     e.response["Error"]["Code"].should.equal("MalformedXML") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # And 101: | 
					
						
							|  |  |  |     many_rules = [{"AllowedOrigins": ["*"], "AllowedMethods": ["GET"]}] * 101 | 
					
						
							| 
									
										
										
										
											2020-10-06 07:54:49 +02:00
										 |  |  |     with pytest.raises(ClientError) as err: | 
					
						
							| 
									
										
										
										
											2017-09-07 11:30:05 -07:00
										 |  |  |         s3.put_bucket_cors( | 
					
						
							|  |  |  |             Bucket=bucket_name, CORSConfiguration={"CORSRules": many_rules} | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2020-10-06 08:04:09 +02:00
										 |  |  |     e = err.value | 
					
						
							| 
									
										
										
										
											2017-09-07 11:30:05 -07:00
										 |  |  |     e.response["Error"]["Code"].should.equal("MalformedXML") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_s3 | 
					
						
							| 
									
										
										
										
											2022-02-24 20:42:38 -01:00
										 |  |  | def test_get_bucket_cors(): | 
					
						
							| 
									
										
										
										
											2020-02-02 10:36:51 +00:00
										 |  |  |     s3 = boto3.client("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							| 
									
										
										
										
											2017-09-07 11:30:05 -07:00
										 |  |  |     bucket_name = "mybucket" | 
					
						
							|  |  |  |     s3.create_bucket(Bucket=bucket_name) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Without CORS: | 
					
						
							| 
									
										
										
										
											2020-10-06 07:54:49 +02:00
										 |  |  |     with pytest.raises(ClientError) as err: | 
					
						
							| 
									
										
										
										
											2017-09-07 11:30:05 -07:00
										 |  |  |         s3.get_bucket_cors(Bucket=bucket_name) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-06 08:04:09 +02:00
										 |  |  |     e = err.value | 
					
						
							| 
									
										
										
										
											2017-09-07 11:30:05 -07:00
										 |  |  |     e.response["Error"]["Code"].should.equal("NoSuchCORSConfiguration") | 
					
						
							|  |  |  |     e.response["Error"]["Message"].should.equal("The CORS configuration does not exist") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     s3.put_bucket_cors( | 
					
						
							|  |  |  |         Bucket=bucket_name, | 
					
						
							|  |  |  |         CORSConfiguration={ | 
					
						
							|  |  |  |             "CORSRules": [ | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                     "AllowedOrigins": ["*"], | 
					
						
							|  |  |  |                     "AllowedMethods": ["GET", "POST"], | 
					
						
							|  |  |  |                     "AllowedHeaders": ["Authorization"], | 
					
						
							|  |  |  |                     "ExposeHeaders": ["x-amz-request-id"], | 
					
						
							|  |  |  |                     "MaxAgeSeconds": 123, | 
					
						
							|  |  |  |                 }, | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                     "AllowedOrigins": ["*"], | 
					
						
							|  |  |  |                     "AllowedMethods": ["PUT"], | 
					
						
							|  |  |  |                     "AllowedHeaders": ["Authorization"], | 
					
						
							|  |  |  |                     "ExposeHeaders": ["x-amz-request-id"], | 
					
						
							|  |  |  |                     "MaxAgeSeconds": 123, | 
					
						
							|  |  |  |                 }, | 
					
						
							|  |  |  |             ] | 
					
						
							|  |  |  |         }, | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     resp = s3.get_bucket_cors(Bucket=bucket_name) | 
					
						
							|  |  |  |     resp["ResponseMetadata"]["HTTPStatusCode"].should.equal(200) | 
					
						
							|  |  |  |     len(resp["CORSRules"]).should.equal(2) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_s3 | 
					
						
							| 
									
										
										
										
											2022-02-24 20:42:38 -01:00
										 |  |  | def test_delete_bucket_cors(): | 
					
						
							| 
									
										
										
										
											2020-02-02 10:36:51 +00:00
										 |  |  |     s3 = boto3.client("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							| 
									
										
										
										
											2017-09-07 11:30:05 -07:00
										 |  |  |     bucket_name = "mybucket" | 
					
						
							|  |  |  |     s3.create_bucket(Bucket=bucket_name) | 
					
						
							|  |  |  |     s3.put_bucket_cors( | 
					
						
							|  |  |  |         Bucket=bucket_name, | 
					
						
							|  |  |  |         CORSConfiguration={ | 
					
						
							|  |  |  |             "CORSRules": [{"AllowedOrigins": ["*"], "AllowedMethods": ["GET"]}] | 
					
						
							|  |  |  |         }, | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     resp = s3.delete_bucket_cors(Bucket=bucket_name) | 
					
						
							|  |  |  |     resp["ResponseMetadata"]["HTTPStatusCode"].should.equal(204) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Verify deletion: | 
					
						
							| 
									
										
										
										
											2020-10-06 07:54:49 +02:00
										 |  |  |     with pytest.raises(ClientError) as err: | 
					
						
							| 
									
										
										
										
											2017-09-07 11:30:05 -07:00
										 |  |  |         s3.get_bucket_cors(Bucket=bucket_name) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-06 08:04:09 +02:00
										 |  |  |     e = err.value | 
					
						
							| 
									
										
										
										
											2017-09-07 11:30:05 -07:00
										 |  |  |     e.response["Error"]["Code"].should.equal("NoSuchCORSConfiguration") | 
					
						
							|  |  |  |     e.response["Error"]["Message"].should.equal("The CORS configuration does not exist") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-21 09:11:24 -07:00
										 |  |  | @mock_s3 | 
					
						
							|  |  |  | def test_put_bucket_notification(): | 
					
						
							| 
									
										
										
										
											2020-02-02 10:36:51 +00:00
										 |  |  |     s3 = boto3.client("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							| 
									
										
										
										
											2018-03-21 09:11:24 -07:00
										 |  |  |     s3.create_bucket(Bucket="bucket") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # With no configuration: | 
					
						
							|  |  |  |     result = s3.get_bucket_notification(Bucket="bucket") | 
					
						
							|  |  |  |     assert not result.get("TopicConfigurations") | 
					
						
							|  |  |  |     assert not result.get("QueueConfigurations") | 
					
						
							|  |  |  |     assert not result.get("LambdaFunctionConfigurations") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Place proper topic configuration: | 
					
						
							|  |  |  |     s3.put_bucket_notification_configuration( | 
					
						
							|  |  |  |         Bucket="bucket", | 
					
						
							|  |  |  |         NotificationConfiguration={ | 
					
						
							|  |  |  |             "TopicConfigurations": [ | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                     "TopicArn": "arn:aws:sns:us-east-1:012345678910:mytopic", | 
					
						
							|  |  |  |                     "Events": ["s3:ObjectCreated:*", "s3:ObjectRemoved:*"], | 
					
						
							|  |  |  |                 }, | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                     "TopicArn": "arn:aws:sns:us-east-1:012345678910:myothertopic", | 
					
						
							|  |  |  |                     "Events": ["s3:ObjectCreated:*"], | 
					
						
							|  |  |  |                     "Filter": { | 
					
						
							|  |  |  |                         "Key": { | 
					
						
							|  |  |  |                             "FilterRules": [ | 
					
						
							|  |  |  |                                 {"Name": "prefix", "Value": "images/"}, | 
					
						
							|  |  |  |                                 {"Name": "suffix", "Value": "png"}, | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |                             ] | 
					
						
							| 
									
										
										
										
											2018-03-21 09:11:24 -07:00
										 |  |  |                         } | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |                     }, | 
					
						
							|  |  |  |                 }, | 
					
						
							| 
									
										
										
										
											2018-03-21 09:11:24 -07:00
										 |  |  |             ] | 
					
						
							|  |  |  |         }, | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Verify to completion: | 
					
						
							|  |  |  |     result = s3.get_bucket_notification_configuration(Bucket="bucket") | 
					
						
							|  |  |  |     assert len(result["TopicConfigurations"]) == 2 | 
					
						
							|  |  |  |     assert not result.get("QueueConfigurations") | 
					
						
							|  |  |  |     assert not result.get("LambdaFunctionConfigurations") | 
					
						
							|  |  |  |     assert ( | 
					
						
							|  |  |  |         result["TopicConfigurations"][0]["TopicArn"] | 
					
						
							|  |  |  |         == "arn:aws:sns:us-east-1:012345678910:mytopic" | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     ) | 
					
						
							| 
									
										
										
										
											2018-03-21 09:11:24 -07:00
										 |  |  |     assert ( | 
					
						
							|  |  |  |         result["TopicConfigurations"][1]["TopicArn"] | 
					
						
							|  |  |  |         == "arn:aws:sns:us-east-1:012345678910:myothertopic" | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     ) | 
					
						
							| 
									
										
										
										
											2018-03-21 09:11:24 -07:00
										 |  |  |     assert len(result["TopicConfigurations"][0]["Events"]) == 2 | 
					
						
							|  |  |  |     assert len(result["TopicConfigurations"][1]["Events"]) == 1 | 
					
						
							|  |  |  |     assert result["TopicConfigurations"][0]["Events"][0] == "s3:ObjectCreated:*" | 
					
						
							|  |  |  |     assert result["TopicConfigurations"][0]["Events"][1] == "s3:ObjectRemoved:*" | 
					
						
							|  |  |  |     assert result["TopicConfigurations"][1]["Events"][0] == "s3:ObjectCreated:*" | 
					
						
							|  |  |  |     assert result["TopicConfigurations"][0]["Id"] | 
					
						
							|  |  |  |     assert result["TopicConfigurations"][1]["Id"] | 
					
						
							|  |  |  |     assert not result["TopicConfigurations"][0].get("Filter") | 
					
						
							|  |  |  |     assert len(result["TopicConfigurations"][1]["Filter"]["Key"]["FilterRules"]) == 2 | 
					
						
							|  |  |  |     assert ( | 
					
						
							|  |  |  |         result["TopicConfigurations"][1]["Filter"]["Key"]["FilterRules"][0]["Name"] | 
					
						
							|  |  |  |         == "prefix" | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     ) | 
					
						
							| 
									
										
										
										
											2018-03-21 09:11:24 -07:00
										 |  |  |     assert ( | 
					
						
							|  |  |  |         result["TopicConfigurations"][1]["Filter"]["Key"]["FilterRules"][0]["Value"] | 
					
						
							|  |  |  |         == "images/" | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     ) | 
					
						
							| 
									
										
										
										
											2018-03-21 09:11:24 -07:00
										 |  |  |     assert ( | 
					
						
							|  |  |  |         result["TopicConfigurations"][1]["Filter"]["Key"]["FilterRules"][1]["Name"] | 
					
						
							|  |  |  |         == "suffix" | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     ) | 
					
						
							| 
									
										
										
										
											2018-03-21 09:11:24 -07:00
										 |  |  |     assert ( | 
					
						
							|  |  |  |         result["TopicConfigurations"][1]["Filter"]["Key"]["FilterRules"][1]["Value"] | 
					
						
							|  |  |  |         == "png" | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     ) | 
					
						
							| 
									
										
										
										
											2018-03-21 09:11:24 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # Place proper queue configuration: | 
					
						
							|  |  |  |     s3.put_bucket_notification_configuration( | 
					
						
							|  |  |  |         Bucket="bucket", | 
					
						
							|  |  |  |         NotificationConfiguration={ | 
					
						
							|  |  |  |             "QueueConfigurations": [ | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                     "Id": "SomeID", | 
					
						
							|  |  |  |                     "QueueArn": "arn:aws:sqs:us-east-1:012345678910:myQueue", | 
					
						
							|  |  |  |                     "Events": ["s3:ObjectCreated:*"], | 
					
						
							|  |  |  |                     "Filter": { | 
					
						
							|  |  |  |                         "Key": {"FilterRules": [{"Name": "prefix", "Value": "images/"}]} | 
					
						
							|  |  |  |                     }, | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             ] | 
					
						
							|  |  |  |         }, | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     result = s3.get_bucket_notification_configuration(Bucket="bucket") | 
					
						
							|  |  |  |     assert len(result["QueueConfigurations"]) == 1 | 
					
						
							|  |  |  |     assert not result.get("TopicConfigurations") | 
					
						
							|  |  |  |     assert not result.get("LambdaFunctionConfigurations") | 
					
						
							|  |  |  |     assert result["QueueConfigurations"][0]["Id"] == "SomeID" | 
					
						
							|  |  |  |     assert ( | 
					
						
							|  |  |  |         result["QueueConfigurations"][0]["QueueArn"] | 
					
						
							|  |  |  |         == "arn:aws:sqs:us-east-1:012345678910:myQueue" | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     ) | 
					
						
							| 
									
										
										
										
											2018-03-21 09:11:24 -07:00
										 |  |  |     assert result["QueueConfigurations"][0]["Events"][0] == "s3:ObjectCreated:*" | 
					
						
							|  |  |  |     assert len(result["QueueConfigurations"][0]["Events"]) == 1 | 
					
						
							|  |  |  |     assert len(result["QueueConfigurations"][0]["Filter"]["Key"]["FilterRules"]) == 1 | 
					
						
							|  |  |  |     assert ( | 
					
						
							|  |  |  |         result["QueueConfigurations"][0]["Filter"]["Key"]["FilterRules"][0]["Name"] | 
					
						
							|  |  |  |         == "prefix" | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     ) | 
					
						
							| 
									
										
										
										
											2018-03-21 09:11:24 -07:00
										 |  |  |     assert ( | 
					
						
							|  |  |  |         result["QueueConfigurations"][0]["Filter"]["Key"]["FilterRules"][0]["Value"] | 
					
						
							|  |  |  |         == "images/" | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     ) | 
					
						
							| 
									
										
										
										
											2018-03-21 09:11:24 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # Place proper Lambda configuration: | 
					
						
							|  |  |  |     s3.put_bucket_notification_configuration( | 
					
						
							|  |  |  |         Bucket="bucket", | 
					
						
							|  |  |  |         NotificationConfiguration={ | 
					
						
							|  |  |  |             "LambdaFunctionConfigurations": [ | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                     "LambdaFunctionArn": "arn:aws:lambda:us-east-1:012345678910:function:lambda", | 
					
						
							|  |  |  |                     "Events": ["s3:ObjectCreated:*"], | 
					
						
							|  |  |  |                     "Filter": { | 
					
						
							|  |  |  |                         "Key": {"FilterRules": [{"Name": "prefix", "Value": "images/"}]} | 
					
						
							|  |  |  |                     }, | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             ] | 
					
						
							|  |  |  |         }, | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     result = s3.get_bucket_notification_configuration(Bucket="bucket") | 
					
						
							|  |  |  |     assert len(result["LambdaFunctionConfigurations"]) == 1 | 
					
						
							|  |  |  |     assert not result.get("TopicConfigurations") | 
					
						
							|  |  |  |     assert not result.get("QueueConfigurations") | 
					
						
							|  |  |  |     assert result["LambdaFunctionConfigurations"][0]["Id"] | 
					
						
							|  |  |  |     assert ( | 
					
						
							|  |  |  |         result["LambdaFunctionConfigurations"][0]["LambdaFunctionArn"] | 
					
						
							| 
									
										
										
										
											2019-10-03 18:00:07 -07:00
										 |  |  |         == "arn:aws:lambda:us-east-1:012345678910:function:lambda" | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     ) | 
					
						
							| 
									
										
										
										
											2018-03-21 09:11:24 -07:00
										 |  |  |     assert ( | 
					
						
							|  |  |  |         result["LambdaFunctionConfigurations"][0]["Events"][0] == "s3:ObjectCreated:*" | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     ) | 
					
						
							| 
									
										
										
										
											2018-03-21 09:11:24 -07:00
										 |  |  |     assert len(result["LambdaFunctionConfigurations"][0]["Events"]) == 1 | 
					
						
							|  |  |  |     assert ( | 
					
						
							|  |  |  |         len(result["LambdaFunctionConfigurations"][0]["Filter"]["Key"]["FilterRules"]) | 
					
						
							|  |  |  |         == 1 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     ) | 
					
						
							| 
									
										
										
										
											2018-03-21 09:11:24 -07:00
										 |  |  |     assert ( | 
					
						
							|  |  |  |         result["LambdaFunctionConfigurations"][0]["Filter"]["Key"]["FilterRules"][0][ | 
					
						
							|  |  |  |             "Name" | 
					
						
							|  |  |  |         ] | 
					
						
							|  |  |  |         == "prefix" | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     ) | 
					
						
							| 
									
										
										
										
											2018-03-21 09:11:24 -07:00
										 |  |  |     assert ( | 
					
						
							|  |  |  |         result["LambdaFunctionConfigurations"][0]["Filter"]["Key"]["FilterRules"][0][ | 
					
						
							|  |  |  |             "Value" | 
					
						
							|  |  |  |         ] | 
					
						
							|  |  |  |         == "images/" | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     ) | 
					
						
							| 
									
										
										
										
											2018-03-21 09:11:24 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # And with all 3 set: | 
					
						
							|  |  |  |     s3.put_bucket_notification_configuration( | 
					
						
							|  |  |  |         Bucket="bucket", | 
					
						
							|  |  |  |         NotificationConfiguration={ | 
					
						
							|  |  |  |             "TopicConfigurations": [ | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                     "TopicArn": "arn:aws:sns:us-east-1:012345678910:mytopic", | 
					
						
							|  |  |  |                     "Events": ["s3:ObjectCreated:*", "s3:ObjectRemoved:*"], | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             ], | 
					
						
							|  |  |  |             "LambdaFunctionConfigurations": [ | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                     "LambdaFunctionArn": "arn:aws:lambda:us-east-1:012345678910:function:lambda", | 
					
						
							|  |  |  |                     "Events": ["s3:ObjectCreated:*"], | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             ], | 
					
						
							|  |  |  |             "QueueConfigurations": [ | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                     "QueueArn": "arn:aws:sqs:us-east-1:012345678910:myQueue", | 
					
						
							|  |  |  |                     "Events": ["s3:ObjectCreated:*"], | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             ], | 
					
						
							|  |  |  |         }, | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     result = s3.get_bucket_notification_configuration(Bucket="bucket") | 
					
						
							|  |  |  |     assert len(result["LambdaFunctionConfigurations"]) == 1 | 
					
						
							|  |  |  |     assert len(result["TopicConfigurations"]) == 1 | 
					
						
							|  |  |  |     assert len(result["QueueConfigurations"]) == 1 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # And clear it out: | 
					
						
							|  |  |  |     s3.put_bucket_notification_configuration( | 
					
						
							|  |  |  |         Bucket="bucket", NotificationConfiguration={} | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     result = s3.get_bucket_notification_configuration(Bucket="bucket") | 
					
						
							|  |  |  |     assert not result.get("TopicConfigurations") | 
					
						
							|  |  |  |     assert not result.get("QueueConfigurations") | 
					
						
							|  |  |  |     assert not result.get("LambdaFunctionConfigurations") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_s3 | 
					
						
							|  |  |  | def test_put_bucket_notification_errors(): | 
					
						
							| 
									
										
										
										
											2020-02-02 10:36:51 +00:00
										 |  |  |     s3 = boto3.client("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							| 
									
										
										
										
											2018-03-21 09:11:24 -07:00
										 |  |  |     s3.create_bucket(Bucket="bucket") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # With incorrect ARNs: | 
					
						
							| 
									
										
										
										
											2021-10-18 19:44:29 +00:00
										 |  |  |     for tech in ["Queue", "Topic", "LambdaFunction"]: | 
					
						
							| 
									
										
										
										
											2020-10-06 07:54:49 +02:00
										 |  |  |         with pytest.raises(ClientError) as err: | 
					
						
							| 
									
										
										
										
											2018-03-21 09:11:24 -07:00
										 |  |  |             s3.put_bucket_notification_configuration( | 
					
						
							|  |  |  |                 Bucket="bucket", | 
					
						
							|  |  |  |                 NotificationConfiguration={ | 
					
						
							| 
									
										
										
										
											2022-11-17 21:41:08 -01:00
										 |  |  |                     f"{tech}Configurations": [ | 
					
						
							| 
									
										
										
										
											2018-03-21 09:11:24 -07:00
										 |  |  |                         { | 
					
						
							| 
									
										
										
										
											2022-11-17 21:41:08 -01:00
										 |  |  |                             f"{tech}Arn": "arn:aws:{}:us-east-1:012345678910:lksajdfkldskfj", | 
					
						
							| 
									
										
										
										
											2018-03-21 09:11:24 -07:00
										 |  |  |                             "Events": ["s3:ObjectCreated:*"], | 
					
						
							|  |  |  |                         } | 
					
						
							|  |  |  |                     ] | 
					
						
							|  |  |  |                 }, | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-06 08:04:09 +02:00
										 |  |  |         assert err.value.response["Error"]["Code"] == "InvalidArgument" | 
					
						
							| 
									
										
										
										
											2020-10-06 08:46:05 +02:00
										 |  |  |         assert err.value.response["Error"]["Message"] == "The ARN is not well formed" | 
					
						
							| 
									
										
										
										
											2018-03-21 09:11:24 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # Region not the same as the bucket: | 
					
						
							| 
									
										
										
										
											2020-10-06 07:54:49 +02:00
										 |  |  |     with pytest.raises(ClientError) as err: | 
					
						
							| 
									
										
										
										
											2018-03-21 09:11:24 -07:00
										 |  |  |         s3.put_bucket_notification_configuration( | 
					
						
							|  |  |  |             Bucket="bucket", | 
					
						
							|  |  |  |             NotificationConfiguration={ | 
					
						
							|  |  |  |                 "QueueConfigurations": [ | 
					
						
							|  |  |  |                     { | 
					
						
							|  |  |  |                         "QueueArn": "arn:aws:sqs:us-west-2:012345678910:lksajdfkldskfj", | 
					
						
							|  |  |  |                         "Events": ["s3:ObjectCreated:*"], | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                 ] | 
					
						
							|  |  |  |             }, | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-06 08:04:09 +02:00
										 |  |  |     assert err.value.response["Error"]["Code"] == "InvalidArgument" | 
					
						
							| 
									
										
										
										
											2018-03-21 09:11:24 -07:00
										 |  |  |     assert ( | 
					
						
							| 
									
										
										
										
											2020-10-06 08:04:09 +02:00
										 |  |  |         err.value.response["Error"]["Message"] | 
					
						
							| 
									
										
										
										
											2019-10-03 18:00:07 -07:00
										 |  |  |         == "The notification destination service region is not valid for the bucket location constraint" | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     ) | 
					
						
							| 
									
										
										
										
											2018-03-21 09:11:24 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # Invalid event name: | 
					
						
							| 
									
										
										
										
											2020-10-06 07:54:49 +02:00
										 |  |  |     with pytest.raises(ClientError) as err: | 
					
						
							| 
									
										
										
										
											2018-03-21 09:11:24 -07:00
										 |  |  |         s3.put_bucket_notification_configuration( | 
					
						
							|  |  |  |             Bucket="bucket", | 
					
						
							|  |  |  |             NotificationConfiguration={ | 
					
						
							|  |  |  |                 "QueueConfigurations": [ | 
					
						
							|  |  |  |                     { | 
					
						
							|  |  |  |                         "QueueArn": "arn:aws:sqs:us-east-1:012345678910:lksajdfkldskfj", | 
					
						
							|  |  |  |                         "Events": ["notarealeventname"], | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                 ] | 
					
						
							|  |  |  |             }, | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2020-10-06 08:04:09 +02:00
										 |  |  |     assert err.value.response["Error"]["Code"] == "InvalidArgument" | 
					
						
							| 
									
										
										
										
											2018-03-21 09:11:24 -07:00
										 |  |  |     assert ( | 
					
						
							| 
									
										
										
										
											2020-10-06 08:04:09 +02:00
										 |  |  |         err.value.response["Error"]["Message"] | 
					
						
							| 
									
										
										
										
											2018-03-21 09:11:24 -07:00
										 |  |  |         == "The event is not supported for notifications" | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     ) | 
					
						
							| 
									
										
										
										
											2018-03-21 09:11:24 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-29 21:56:48 +03:00
										 |  |  | @mock_s3 | 
					
						
							| 
									
										
										
										
											2022-02-24 20:42:38 -01:00
										 |  |  | def test_list_object_versions(): | 
					
						
							| 
									
										
										
										
											2020-02-02 10:36:51 +00:00
										 |  |  |     s3 = boto3.client("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							| 
									
										
										
										
											2021-10-14 18:13:40 +00:00
										 |  |  |     bucket_name = "000" + str(uuid4()) | 
					
						
							| 
									
										
										
										
											2017-04-29 21:56:48 +03:00
										 |  |  |     key = "key-with-versions" | 
					
						
							|  |  |  |     s3.create_bucket(Bucket=bucket_name) | 
					
						
							| 
									
										
										
										
											2017-05-14 20:00:26 +03:00
										 |  |  |     s3.put_bucket_versioning( | 
					
						
							|  |  |  |         Bucket=bucket_name, VersioningConfiguration={"Status": "Enabled"} | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2021-07-26 07:40:39 +01:00
										 |  |  |     items = (b"v1", b"v2") | 
					
						
							| 
									
										
										
										
											2017-04-30 08:03:46 +03:00
										 |  |  |     for body in items: | 
					
						
							| 
									
										
										
										
											2017-04-29 21:56:48 +03:00
										 |  |  |         s3.put_object(Bucket=bucket_name, Key=key, Body=body) | 
					
						
							|  |  |  |     response = s3.list_object_versions(Bucket=bucket_name) | 
					
						
							|  |  |  |     # Two object versions should be returned | 
					
						
							|  |  |  |     len(response["Versions"]).should.equal(2) | 
					
						
							|  |  |  |     keys = set([item["Key"] for item in response["Versions"]]) | 
					
						
							|  |  |  |     keys.should.equal({key}) | 
					
						
							| 
									
										
										
										
											2021-01-15 23:58:28 +05:30
										 |  |  | 
 | 
					
						
							|  |  |  |     # the first item in the list should be the latest | 
					
						
							|  |  |  |     response["Versions"][0]["IsLatest"].should.equal(True) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-29 21:56:48 +03:00
										 |  |  |     # Test latest object version is returned | 
					
						
							|  |  |  |     response = s3.get_object(Bucket=bucket_name, Key=key) | 
					
						
							| 
									
										
										
										
											2017-04-30 08:03:46 +03:00
										 |  |  |     response["Body"].read().should.equal(items[-1]) | 
					
						
							| 
									
										
										
										
											2017-04-29 21:56:48 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-14 18:13:40 +00:00
										 |  |  | @mock_s3 | 
					
						
							| 
									
										
										
										
											2022-02-24 20:42:38 -01:00
										 |  |  | def test_list_object_versions_with_delimiter(): | 
					
						
							| 
									
										
										
										
											2021-10-14 18:13:40 +00:00
										 |  |  |     s3 = boto3.client("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							|  |  |  |     bucket_name = "000" + str(uuid4()) | 
					
						
							|  |  |  |     s3.create_bucket(Bucket=bucket_name) | 
					
						
							|  |  |  |     s3.put_bucket_versioning( | 
					
						
							|  |  |  |         Bucket=bucket_name, VersioningConfiguration={"Status": "Enabled"} | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     for key_index in list(range(1, 5)) + list(range(10, 14)): | 
					
						
							|  |  |  |         for version_index in range(1, 4): | 
					
						
							|  |  |  |             body = f"data-{version_index}".encode("UTF-8") | 
					
						
							|  |  |  |             s3.put_object( | 
					
						
							|  |  |  |                 Bucket=bucket_name, Key=f"key{key_index}-with-data", Body=body | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  |             s3.put_object( | 
					
						
							|  |  |  |                 Bucket=bucket_name, Key=f"key{key_index}-without-data", Body=b"" | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  |     response = s3.list_object_versions(Bucket=bucket_name) | 
					
						
							|  |  |  |     # All object versions should be returned | 
					
						
							|  |  |  |     len(response["Versions"]).should.equal( | 
					
						
							|  |  |  |         48 | 
					
						
							|  |  |  |     )  # 8 keys * 2 (one with, one without) * 3 versions per key | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Use start of key as delimiter | 
					
						
							|  |  |  |     response = s3.list_object_versions(Bucket=bucket_name, Delimiter="key1") | 
					
						
							|  |  |  |     response.should.have.key("CommonPrefixes").equal([{"Prefix": "key1"}]) | 
					
						
							|  |  |  |     response.should.have.key("Delimiter").equal("key1") | 
					
						
							|  |  |  |     # 3 keys that do not contain the phrase 'key1' (key2, key3, key4) * * 2 *  3 | 
					
						
							|  |  |  |     response.should.have.key("Versions").length_of(18) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Use in-between key as delimiter | 
					
						
							|  |  |  |     response = s3.list_object_versions(Bucket=bucket_name, Delimiter="-with-") | 
					
						
							|  |  |  |     response.should.have.key("CommonPrefixes").equal( | 
					
						
							|  |  |  |         [ | 
					
						
							|  |  |  |             {"Prefix": "key1-with-"}, | 
					
						
							|  |  |  |             {"Prefix": "key10-with-"}, | 
					
						
							|  |  |  |             {"Prefix": "key11-with-"}, | 
					
						
							|  |  |  |             {"Prefix": "key12-with-"}, | 
					
						
							|  |  |  |             {"Prefix": "key13-with-"}, | 
					
						
							|  |  |  |             {"Prefix": "key2-with-"}, | 
					
						
							|  |  |  |             {"Prefix": "key3-with-"}, | 
					
						
							|  |  |  |             {"Prefix": "key4-with-"}, | 
					
						
							|  |  |  |         ] | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     response.should.have.key("Delimiter").equal("-with-") | 
					
						
							|  |  |  |     # key(1/10/11/12/13)-without, key(2/3/4)-without | 
					
						
							|  |  |  |     response.should.have.key("Versions").length_of(8 * 1 * 3) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Use in-between key as delimiter | 
					
						
							|  |  |  |     response = s3.list_object_versions(Bucket=bucket_name, Delimiter="1-with-") | 
					
						
							|  |  |  |     response.should.have.key("CommonPrefixes").equal( | 
					
						
							|  |  |  |         [{"Prefix": "key1-with-"}, {"Prefix": "key11-with-"}] | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     response.should.have.key("Delimiter").equal("1-with-") | 
					
						
							|  |  |  |     response.should.have.key("Versions").length_of(42) | 
					
						
							|  |  |  |     all_keys = set([v["Key"] for v in response["Versions"]]) | 
					
						
							|  |  |  |     all_keys.should.contain("key1-without-data") | 
					
						
							|  |  |  |     all_keys.shouldnt.contain("key1-with-data") | 
					
						
							|  |  |  |     all_keys.should.contain("key4-with-data") | 
					
						
							|  |  |  |     all_keys.should.contain("key4-without-data") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Use in-between key as delimiter + prefix | 
					
						
							|  |  |  |     response = s3.list_object_versions( | 
					
						
							|  |  |  |         Bucket=bucket_name, Prefix="key1", Delimiter="with-" | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     response.should.have.key("CommonPrefixes").equal( | 
					
						
							|  |  |  |         [ | 
					
						
							|  |  |  |             {"Prefix": "key1-with-"}, | 
					
						
							|  |  |  |             {"Prefix": "key10-with-"}, | 
					
						
							|  |  |  |             {"Prefix": "key11-with-"}, | 
					
						
							|  |  |  |             {"Prefix": "key12-with-"}, | 
					
						
							|  |  |  |             {"Prefix": "key13-with-"}, | 
					
						
							|  |  |  |         ] | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     response.should.have.key("Delimiter").equal("with-") | 
					
						
							|  |  |  |     response.should.have.key("KeyMarker").equal("") | 
					
						
							|  |  |  |     response.shouldnt.have.key("NextKeyMarker") | 
					
						
							|  |  |  |     response.should.have.key("Versions").length_of(15) | 
					
						
							|  |  |  |     all_keys = set([v["Key"] for v in response["Versions"]]) | 
					
						
							|  |  |  |     all_keys.should.equal( | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             "key1-without-data", | 
					
						
							|  |  |  |             "key10-without-data", | 
					
						
							|  |  |  |             "key11-without-data", | 
					
						
							|  |  |  |             "key13-without-data", | 
					
						
							|  |  |  |             "key12-without-data", | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Start at KeyMarker, and filter using Prefix+Delimiter for all subsequent keys | 
					
						
							|  |  |  |     response = s3.list_object_versions( | 
					
						
							|  |  |  |         Bucket=bucket_name, Prefix="key1", Delimiter="with-", KeyMarker="key11" | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     response.should.have.key("CommonPrefixes").equal( | 
					
						
							|  |  |  |         [ | 
					
						
							|  |  |  |             {"Prefix": "key11-with-"}, | 
					
						
							|  |  |  |             {"Prefix": "key12-with-"}, | 
					
						
							|  |  |  |             {"Prefix": "key13-with-"}, | 
					
						
							|  |  |  |         ] | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     response.should.have.key("Delimiter").equal("with-") | 
					
						
							|  |  |  |     response.should.have.key("KeyMarker").equal("key11") | 
					
						
							|  |  |  |     response.shouldnt.have.key("NextKeyMarker") | 
					
						
							|  |  |  |     response.should.have.key("Versions").length_of(9) | 
					
						
							|  |  |  |     all_keys = set([v["Key"] for v in response["Versions"]]) | 
					
						
							|  |  |  |     all_keys.should.equal( | 
					
						
							|  |  |  |         {"key11-without-data", "key12-without-data", "key13-without-data"} | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-14 13:49:33 +00:00
										 |  |  |     # Delimiter with Prefix being the entire key | 
					
						
							|  |  |  |     response = s3.list_object_versions( | 
					
						
							|  |  |  |         Bucket=bucket_name, Prefix="key1-with-data", Delimiter="-" | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     response.should.have.key("Versions").length_of(3) | 
					
						
							|  |  |  |     response.shouldnt.have.key("CommonPrefixes") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Delimiter without prefix | 
					
						
							|  |  |  |     response = s3.list_object_versions(Bucket=bucket_name, Delimiter="-with-") | 
					
						
							|  |  |  |     response["CommonPrefixes"].should.have.length_of(8) | 
					
						
							|  |  |  |     response["CommonPrefixes"].should.contain({"Prefix": "key1-with-"}) | 
					
						
							|  |  |  |     # Should return all keys -without-data | 
					
						
							|  |  |  |     response.should.have.key("Versions").length_of(24) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-14 18:13:40 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-24 21:04:34 -01:00
										 |  |  | @mock_s3 | 
					
						
							|  |  |  | def test_list_object_versions_with_delimiter_for_deleted_objects(): | 
					
						
							|  |  |  |     bucket_name = "tests_bucket" | 
					
						
							|  |  |  |     client = boto3.client("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							|  |  |  |     # Create bucket with versioning | 
					
						
							|  |  |  |     client.create_bucket(Bucket=bucket_name) | 
					
						
							|  |  |  |     client.put_bucket_versioning( | 
					
						
							|  |  |  |         Bucket=bucket_name, | 
					
						
							|  |  |  |         VersioningConfiguration={"MFADelete": "Disabled", "Status": "Enabled"}, | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Create a history of objects | 
					
						
							|  |  |  |     for pos in range(2): | 
					
						
							|  |  |  |         client.put_object( | 
					
						
							|  |  |  |             Bucket=bucket_name, Key=f"obj_{pos}", Body=f"object {pos}".encode("utf-8") | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for pos in range(2): | 
					
						
							|  |  |  |         client.put_object( | 
					
						
							|  |  |  |             Bucket=bucket_name, | 
					
						
							|  |  |  |             Key=f"hist_obj_{pos}", | 
					
						
							|  |  |  |             Body=f"history object {pos}".encode("utf-8"), | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         for hist_pos in range(2): | 
					
						
							|  |  |  |             client.put_object( | 
					
						
							|  |  |  |                 Bucket=bucket_name, | 
					
						
							|  |  |  |                 Key=f"hist_obj_{pos}", | 
					
						
							|  |  |  |                 Body=f"object {pos} {hist_pos}".encode("utf-8"), | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for pos in range(2): | 
					
						
							|  |  |  |         client.put_object( | 
					
						
							|  |  |  |             Bucket=bucket_name, | 
					
						
							|  |  |  |             Key=f"del_obj_{pos}", | 
					
						
							|  |  |  |             Body=f"deleted object {pos}".encode("utf-8"), | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         client.delete_object(Bucket=bucket_name, Key=f"del_obj_{pos}") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Verify we only retrieve the DeleteMarkers that have this prefix | 
					
						
							|  |  |  |     objs = client.list_object_versions(Bucket=bucket_name) | 
					
						
							|  |  |  |     [dm["Key"] for dm in objs["DeleteMarkers"]].should.equal(["del_obj_0", "del_obj_1"]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     hist_objs = client.list_object_versions(Bucket=bucket_name, Prefix="hist_obj") | 
					
						
							|  |  |  |     hist_objs.shouldnt.have.key("DeleteMarkers") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     del_objs = client.list_object_versions(Bucket=bucket_name, Prefix="del_obj_0") | 
					
						
							|  |  |  |     [dm["Key"] for dm in del_objs["DeleteMarkers"]].should.equal(["del_obj_0"]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-08 22:01:27 +01:00
										 |  |  | @mock_s3 | 
					
						
							| 
									
										
										
										
											2022-02-24 20:42:38 -01:00
										 |  |  | def test_list_object_versions_with_versioning_disabled(): | 
					
						
							| 
									
										
										
										
											2020-02-02 10:36:51 +00:00
										 |  |  |     s3 = boto3.client("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							| 
									
										
										
										
											2019-03-08 22:01:27 +01:00
										 |  |  |     bucket_name = "mybucket" | 
					
						
							|  |  |  |     key = "key-with-versions" | 
					
						
							|  |  |  |     s3.create_bucket(Bucket=bucket_name) | 
					
						
							| 
									
										
										
										
											2021-07-26 07:40:39 +01:00
										 |  |  |     items = (b"v1", b"v2") | 
					
						
							| 
									
										
										
										
											2019-03-08 22:01:27 +01:00
										 |  |  |     for body in items: | 
					
						
							|  |  |  |         s3.put_object(Bucket=bucket_name, Key=key, Body=body) | 
					
						
							|  |  |  |     response = s3.list_object_versions(Bucket=bucket_name) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # One object version should be returned | 
					
						
							|  |  |  |     len(response["Versions"]).should.equal(1) | 
					
						
							|  |  |  |     response["Versions"][0]["Key"].should.equal(key) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # The version id should be the string null | 
					
						
							|  |  |  |     response["Versions"][0]["VersionId"].should.equal("null") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Test latest object version is returned | 
					
						
							|  |  |  |     response = s3.get_object(Bucket=bucket_name, Key=key) | 
					
						
							|  |  |  |     response["Body"].read().should.equal(items[-1]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_s3 | 
					
						
							| 
									
										
										
										
											2022-02-24 20:42:38 -01:00
										 |  |  | def test_list_object_versions_with_versioning_enabled_late(): | 
					
						
							| 
									
										
										
										
											2020-02-02 10:36:51 +00:00
										 |  |  |     s3 = boto3.client("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							| 
									
										
										
										
											2019-03-08 22:01:27 +01:00
										 |  |  |     bucket_name = "mybucket" | 
					
						
							|  |  |  |     key = "key-with-versions" | 
					
						
							|  |  |  |     s3.create_bucket(Bucket=bucket_name) | 
					
						
							| 
									
										
										
										
											2021-07-26 07:40:39 +01:00
										 |  |  |     items = (b"v1", b"v2") | 
					
						
							|  |  |  |     s3.put_object(Bucket=bucket_name, Key=key, Body=b"v1") | 
					
						
							| 
									
										
										
										
											2019-03-08 22:01:27 +01:00
										 |  |  |     s3.put_bucket_versioning( | 
					
						
							|  |  |  |         Bucket=bucket_name, VersioningConfiguration={"Status": "Enabled"} | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2021-07-26 07:40:39 +01:00
										 |  |  |     s3.put_object(Bucket=bucket_name, Key=key, Body=b"v2") | 
					
						
							| 
									
										
										
										
											2018-01-05 15:12:45 -05:00
										 |  |  |     response = s3.list_object_versions(Bucket=bucket_name) | 
					
						
							| 
									
										
										
										
											2019-03-08 22:01:27 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # Two object versions should be returned | 
					
						
							|  |  |  |     len(response["Versions"]).should.equal(2) | 
					
						
							|  |  |  |     keys = set([item["Key"] for item in response["Versions"]]) | 
					
						
							|  |  |  |     keys.should.equal({key}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # There should still be a null version id. | 
					
						
							|  |  |  |     versionsId = set([item["VersionId"] for item in response["Versions"]]) | 
					
						
							|  |  |  |     versionsId.should.contain("null") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Test latest object version is returned | 
					
						
							|  |  |  |     response = s3.get_object(Bucket=bucket_name, Key=key) | 
					
						
							|  |  |  |     response["Body"].read().should.equal(items[-1]) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-23 17:16:20 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-22 11:59:01 -07:00
										 |  |  | @mock_s3 | 
					
						
							| 
									
										
										
										
											2022-02-24 20:42:38 -01:00
										 |  |  | def test_bad_prefix_list_object_versions(): | 
					
						
							| 
									
										
										
										
											2020-02-02 10:36:51 +00:00
										 |  |  |     s3 = boto3.client("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							| 
									
										
										
										
											2018-06-22 11:59:01 -07:00
										 |  |  |     bucket_name = "mybucket" | 
					
						
							|  |  |  |     key = "key-with-versions" | 
					
						
							|  |  |  |     bad_prefix = "key-that-does-not-exist" | 
					
						
							|  |  |  |     s3.create_bucket(Bucket=bucket_name) | 
					
						
							|  |  |  |     s3.put_bucket_versioning( | 
					
						
							|  |  |  |         Bucket=bucket_name, VersioningConfiguration={"Status": "Enabled"} | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2021-07-26 07:40:39 +01:00
										 |  |  |     items = (b"v1", b"v2") | 
					
						
							| 
									
										
										
										
											2018-06-22 11:59:01 -07:00
										 |  |  |     for body in items: | 
					
						
							|  |  |  |         s3.put_object(Bucket=bucket_name, Key=key, Body=body) | 
					
						
							|  |  |  |     response = s3.list_object_versions(Bucket=bucket_name, Prefix=bad_prefix) | 
					
						
							|  |  |  |     response["ResponseMetadata"]["HTTPStatusCode"].should.equal(200) | 
					
						
							|  |  |  |     response.should_not.contain("Versions") | 
					
						
							|  |  |  |     response.should_not.contain("DeleteMarkers") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-14 20:00:26 +03:00
										 |  |  | @mock_s3 | 
					
						
							| 
									
										
										
										
											2022-02-24 20:42:38 -01:00
										 |  |  | def test_delete_markers(): | 
					
						
							| 
									
										
										
										
											2020-02-02 10:36:51 +00:00
										 |  |  |     s3 = boto3.client("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							| 
									
										
										
										
											2017-05-14 20:00:26 +03:00
										 |  |  |     bucket_name = "mybucket" | 
					
						
							| 
									
										
										
										
											2017-11-06 21:39:08 +00:00
										 |  |  |     key = "key-with-versions-and-unicode-ó" | 
					
						
							| 
									
										
										
										
											2017-05-14 20:00:26 +03:00
										 |  |  |     s3.create_bucket(Bucket=bucket_name) | 
					
						
							|  |  |  |     s3.put_bucket_versioning( | 
					
						
							|  |  |  |         Bucket=bucket_name, VersioningConfiguration={"Status": "Enabled"} | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2021-07-26 07:40:39 +01:00
										 |  |  |     items = (b"v1", b"v2") | 
					
						
							| 
									
										
										
										
											2017-05-14 20:00:26 +03:00
										 |  |  |     for body in items: | 
					
						
							|  |  |  |         s3.put_object(Bucket=bucket_name, Key=key, Body=body) | 
					
						
							| 
									
										
										
										
											2017-11-06 21:39:08 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     s3.delete_objects(Bucket=bucket_name, Delete={"Objects": [{"Key": key}]}) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-06 07:54:49 +02:00
										 |  |  |     with pytest.raises(ClientError) as e: | 
					
						
							| 
									
										
										
										
											2017-05-14 20:00:26 +03:00
										 |  |  |         s3.get_object(Bucket=bucket_name, Key=key) | 
					
						
							| 
									
										
										
										
											2020-10-06 08:04:09 +02:00
										 |  |  |     e.value.response["Error"]["Code"].should.equal("NoSuchKey") | 
					
						
							| 
									
										
										
										
											2019-03-08 22:01:27 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     response = s3.list_object_versions(Bucket=bucket_name) | 
					
						
							|  |  |  |     response["Versions"].should.have.length_of(2) | 
					
						
							|  |  |  |     response["DeleteMarkers"].should.have.length_of(1) | 
					
						
							| 
									
										
										
										
											2017-05-14 20:00:26 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  |     s3.delete_object( | 
					
						
							| 
									
										
										
										
											2019-03-08 22:01:27 +01:00
										 |  |  |         Bucket=bucket_name, Key=key, VersionId=response["DeleteMarkers"][0]["VersionId"] | 
					
						
							| 
									
										
										
										
											2017-05-14 20:00:26 +03:00
										 |  |  |     ) | 
					
						
							| 
									
										
										
										
											2019-03-08 22:01:27 +01:00
										 |  |  |     response = s3.get_object(Bucket=bucket_name, Key=key) | 
					
						
							| 
									
										
										
										
											2017-05-14 20:00:26 +03:00
										 |  |  |     response["Body"].read().should.equal(items[-1]) | 
					
						
							| 
									
										
										
										
											2019-03-08 22:01:27 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-14 20:00:26 +03:00
										 |  |  |     response = s3.list_object_versions(Bucket=bucket_name) | 
					
						
							|  |  |  |     response["Versions"].should.have.length_of(2) | 
					
						
							| 
									
										
										
										
											2017-11-06 21:39:08 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # We've asserted there is only 2 records so one is newest, one is oldest | 
					
						
							|  |  |  |     latest = list(filter(lambda item: item["IsLatest"], response["Versions"]))[0] | 
					
						
							|  |  |  |     oldest = list(filter(lambda item: not item["IsLatest"], response["Versions"]))[0] | 
					
						
							|  |  |  |     # Double check ordering of version ID's | 
					
						
							| 
									
										
										
										
											2019-03-08 22:01:27 +01:00
										 |  |  |     latest["VersionId"].should_not.equal(oldest["VersionId"]) | 
					
						
							| 
									
										
										
										
											2017-11-06 21:39:08 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # Double check the name is still unicode | 
					
						
							|  |  |  |     latest["Key"].should.equal("key-with-versions-and-unicode-ó") | 
					
						
							|  |  |  |     oldest["Key"].should.equal("key-with-versions-and-unicode-ó") | 
					
						
							| 
									
										
										
										
											2017-05-14 20:00:26 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-05 15:12:45 -05:00
										 |  |  | @mock_s3 | 
					
						
							| 
									
										
										
										
											2022-02-24 20:42:38 -01:00
										 |  |  | def test_multiple_delete_markers(): | 
					
						
							| 
									
										
										
										
											2020-02-02 10:36:51 +00:00
										 |  |  |     s3 = boto3.client("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							| 
									
										
										
										
											2018-01-05 15:12:45 -05:00
										 |  |  |     bucket_name = "mybucket" | 
					
						
							|  |  |  |     key = "key-with-versions-and-unicode-ó" | 
					
						
							|  |  |  |     s3.create_bucket(Bucket=bucket_name) | 
					
						
							|  |  |  |     s3.put_bucket_versioning( | 
					
						
							|  |  |  |         Bucket=bucket_name, VersioningConfiguration={"Status": "Enabled"} | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2021-07-26 07:40:39 +01:00
										 |  |  |     items = (b"v1", b"v2") | 
					
						
							| 
									
										
										
										
											2018-01-05 15:12:45 -05:00
										 |  |  |     for body in items: | 
					
						
							|  |  |  |         s3.put_object(Bucket=bucket_name, Key=key, Body=body) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Delete the object twice to add multiple delete markers | 
					
						
							|  |  |  |     s3.delete_object(Bucket=bucket_name, Key=key) | 
					
						
							|  |  |  |     s3.delete_object(Bucket=bucket_name, Key=key) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     response = s3.list_object_versions(Bucket=bucket_name) | 
					
						
							|  |  |  |     response["DeleteMarkers"].should.have.length_of(2) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-06 07:54:49 +02:00
										 |  |  |     with pytest.raises(ClientError) as e: | 
					
						
							| 
									
										
										
										
											2018-01-05 15:12:45 -05:00
										 |  |  |         s3.get_object(Bucket=bucket_name, Key=key) | 
					
						
							|  |  |  |         e.response["Error"]["Code"].should.equal("404") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Remove both delete markers to restore the object | 
					
						
							|  |  |  |     s3.delete_object( | 
					
						
							| 
									
										
										
										
											2019-03-08 22:01:27 +01:00
										 |  |  |         Bucket=bucket_name, Key=key, VersionId=response["DeleteMarkers"][0]["VersionId"] | 
					
						
							| 
									
										
										
										
											2018-01-05 15:12:45 -05:00
										 |  |  |     ) | 
					
						
							|  |  |  |     s3.delete_object( | 
					
						
							| 
									
										
										
										
											2019-03-08 22:01:27 +01:00
										 |  |  |         Bucket=bucket_name, Key=key, VersionId=response["DeleteMarkers"][1]["VersionId"] | 
					
						
							| 
									
										
										
										
											2018-01-05 15:12:45 -05:00
										 |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     response = s3.get_object(Bucket=bucket_name, Key=key) | 
					
						
							|  |  |  |     response["Body"].read().should.equal(items[-1]) | 
					
						
							|  |  |  |     response = s3.list_object_versions(Bucket=bucket_name) | 
					
						
							|  |  |  |     response["Versions"].should.have.length_of(2) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # We've asserted there is only 2 records so one is newest, one is oldest | 
					
						
							|  |  |  |     latest = list(filter(lambda item: item["IsLatest"], response["Versions"]))[0] | 
					
						
							|  |  |  |     oldest = list(filter(lambda item: not item["IsLatest"], response["Versions"]))[0] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Double check ordering of version ID's | 
					
						
							| 
									
										
										
										
											2019-03-08 22:01:27 +01:00
										 |  |  |     latest["VersionId"].should_not.equal(oldest["VersionId"]) | 
					
						
							| 
									
										
										
										
											2018-01-05 15:12:45 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # Double check the name is still unicode | 
					
						
							|  |  |  |     latest["Key"].should.equal("key-with-versions-and-unicode-ó") | 
					
						
							|  |  |  |     oldest["Key"].should.equal("key-with-versions-and-unicode-ó") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-25 12:19:33 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-03 19:06:49 -04:00
										 |  |  | @mock_s3 | 
					
						
							|  |  |  | def test_get_stream_gzipped(): | 
					
						
							| 
									
										
										
										
											2017-06-03 19:35:23 -04:00
										 |  |  |     payload = b"this is some stuff here" | 
					
						
							| 
									
										
										
										
											2017-06-03 19:06:49 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-02 10:36:51 +00:00
										 |  |  |     s3_client = boto3.client("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							| 
									
										
										
										
											2017-06-03 19:06:49 -04:00
										 |  |  |     s3_client.create_bucket(Bucket="moto-tests") | 
					
						
							|  |  |  |     buffer_ = BytesIO() | 
					
						
							|  |  |  |     with GzipFile(fileobj=buffer_, mode="w") as f: | 
					
						
							|  |  |  |         f.write(payload) | 
					
						
							|  |  |  |     payload_gz = buffer_.getvalue() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     s3_client.put_object( | 
					
						
							|  |  |  |         Bucket="moto-tests", Key="keyname", Body=payload_gz, ContentEncoding="gzip" | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     obj = s3_client.get_object(Bucket="moto-tests", Key="keyname") | 
					
						
							| 
									
										
										
										
											2018-01-02 23:47:57 -05:00
										 |  |  |     res = zlib.decompress(obj["Body"].read(), 16 + zlib.MAX_WBITS) | 
					
						
							| 
									
										
										
										
											2017-06-03 19:06:49 -04:00
										 |  |  |     assert res == payload | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-04 18:55:41 -05:00
										 |  |  | TEST_XML = """\
 | 
					
						
							|  |  |  | <?xml version="1.0" encoding="UTF-8"?> | 
					
						
							|  |  |  | <ns0:WebsiteConfiguration xmlns:ns0="http://s3.amazonaws.com/doc/2006-03-01/"> | 
					
						
							|  |  |  |     <ns0:IndexDocument> | 
					
						
							|  |  |  |         <ns0:Suffix>index.html</ns0:Suffix> | 
					
						
							|  |  |  |     </ns0:IndexDocument> | 
					
						
							|  |  |  |     <ns0:RoutingRules> | 
					
						
							|  |  |  |         <ns0:RoutingRule> | 
					
						
							|  |  |  |             <ns0:Condition> | 
					
						
							|  |  |  |                 <ns0:KeyPrefixEquals>test/testing</ns0:KeyPrefixEquals> | 
					
						
							|  |  |  |             </ns0:Condition> | 
					
						
							|  |  |  |             <ns0:Redirect> | 
					
						
							|  |  |  |                 <ns0:ReplaceKeyWith>test.txt</ns0:ReplaceKeyWith> | 
					
						
							|  |  |  |             </ns0:Redirect> | 
					
						
							|  |  |  |         </ns0:RoutingRule> | 
					
						
							|  |  |  |     </ns0:RoutingRules> | 
					
						
							|  |  |  | </ns0:WebsiteConfiguration> | 
					
						
							|  |  |  | """
 | 
					
						
							| 
									
										
										
										
											2018-11-22 06:08:03 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-23 17:16:20 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-22 06:08:03 -06:00
										 |  |  | @mock_s3 | 
					
						
							| 
									
										
										
										
											2022-02-24 20:42:38 -01:00
										 |  |  | def test_bucket_name_too_long(): | 
					
						
							| 
									
										
										
										
											2020-02-02 10:36:51 +00:00
										 |  |  |     s3 = boto3.client("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							| 
									
										
										
										
											2020-10-06 07:54:49 +02:00
										 |  |  |     with pytest.raises(ClientError) as exc: | 
					
						
							| 
									
										
										
										
											2019-10-03 18:00:07 -07:00
										 |  |  |         s3.create_bucket(Bucket="x" * 64) | 
					
						
							| 
									
										
										
										
											2020-10-06 08:04:09 +02:00
										 |  |  |     exc.value.response["Error"]["Code"].should.equal("InvalidBucketName") | 
					
						
							| 
									
										
										
										
											2018-11-22 06:08:03 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-23 17:16:20 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-22 06:08:03 -06:00
										 |  |  | @mock_s3 | 
					
						
							| 
									
										
										
										
											2022-02-24 20:42:38 -01:00
										 |  |  | def test_bucket_name_too_short(): | 
					
						
							| 
									
										
										
										
											2020-02-02 10:36:51 +00:00
										 |  |  |     s3 = boto3.client("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							| 
									
										
										
										
											2020-10-06 07:54:49 +02:00
										 |  |  |     with pytest.raises(ClientError) as exc: | 
					
						
							| 
									
										
										
										
											2019-10-03 18:00:07 -07:00
										 |  |  |         s3.create_bucket(Bucket="x" * 2) | 
					
						
							| 
									
										
										
										
											2020-10-06 08:04:09 +02:00
										 |  |  |     exc.value.response["Error"]["Code"].should.equal("InvalidBucketName") | 
					
						
							| 
									
										
										
										
											2019-05-25 12:19:00 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-23 17:16:20 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-25 12:19:00 +02:00
										 |  |  | @mock_s3 | 
					
						
							|  |  |  | def test_accelerated_none_when_unspecified(): | 
					
						
							|  |  |  |     bucket_name = "some_bucket" | 
					
						
							| 
									
										
										
										
											2020-02-02 10:36:51 +00:00
										 |  |  |     s3 = boto3.client("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							| 
									
										
										
										
											2019-05-25 12:19:00 +02:00
										 |  |  |     s3.create_bucket(Bucket=bucket_name) | 
					
						
							|  |  |  |     resp = s3.get_bucket_accelerate_configuration(Bucket=bucket_name) | 
					
						
							|  |  |  |     resp.shouldnt.have.key("Status") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-23 17:16:20 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-25 12:19:00 +02:00
										 |  |  | @mock_s3 | 
					
						
							|  |  |  | def test_can_enable_bucket_acceleration(): | 
					
						
							|  |  |  |     bucket_name = "some_bucket" | 
					
						
							| 
									
										
										
										
											2020-02-02 10:36:51 +00:00
										 |  |  |     s3 = boto3.client("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							| 
									
										
										
										
											2019-05-25 12:19:00 +02:00
										 |  |  |     s3.create_bucket(Bucket=bucket_name) | 
					
						
							|  |  |  |     resp = s3.put_bucket_accelerate_configuration( | 
					
						
							|  |  |  |         Bucket=bucket_name, AccelerateConfiguration={"Status": "Enabled"} | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2019-10-03 18:00:07 -07:00
										 |  |  |     resp.keys().should.have.length_of( | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         1 | 
					
						
							| 
									
										
										
										
											2019-10-03 18:00:07 -07:00
										 |  |  |     )  # Response contains nothing (only HTTP headers) | 
					
						
							| 
									
										
										
										
											2019-05-25 12:19:00 +02:00
										 |  |  |     resp = s3.get_bucket_accelerate_configuration(Bucket=bucket_name) | 
					
						
							|  |  |  |     resp.should.have.key("Status") | 
					
						
							|  |  |  |     resp["Status"].should.equal("Enabled") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-23 17:16:20 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-25 12:19:00 +02:00
										 |  |  | @mock_s3 | 
					
						
							|  |  |  | def test_can_suspend_bucket_acceleration(): | 
					
						
							|  |  |  |     bucket_name = "some_bucket" | 
					
						
							| 
									
										
										
										
											2020-02-02 10:36:51 +00:00
										 |  |  |     s3 = boto3.client("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							| 
									
										
										
										
											2019-05-25 12:19:00 +02:00
										 |  |  |     s3.create_bucket(Bucket=bucket_name) | 
					
						
							|  |  |  |     resp = s3.put_bucket_accelerate_configuration( | 
					
						
							|  |  |  |         Bucket=bucket_name, AccelerateConfiguration={"Status": "Enabled"} | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     resp = s3.put_bucket_accelerate_configuration( | 
					
						
							|  |  |  |         Bucket=bucket_name, AccelerateConfiguration={"Status": "Suspended"} | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2019-10-03 18:00:07 -07:00
										 |  |  |     resp.keys().should.have.length_of( | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         1 | 
					
						
							| 
									
										
										
										
											2019-10-03 18:00:07 -07:00
										 |  |  |     )  # Response contains nothing (only HTTP headers) | 
					
						
							| 
									
										
										
										
											2019-05-25 12:19:00 +02:00
										 |  |  |     resp = s3.get_bucket_accelerate_configuration(Bucket=bucket_name) | 
					
						
							|  |  |  |     resp.should.have.key("Status") | 
					
						
							|  |  |  |     resp["Status"].should.equal("Suspended") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-23 17:16:20 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-25 12:19:00 +02:00
										 |  |  | @mock_s3 | 
					
						
							|  |  |  | def test_suspending_acceleration_on_not_configured_bucket_does_nothing(): | 
					
						
							|  |  |  |     bucket_name = "some_bucket" | 
					
						
							|  |  |  |     s3 = boto3.client("s3") | 
					
						
							| 
									
										
										
										
											2020-02-02 10:36:51 +00:00
										 |  |  |     s3.create_bucket( | 
					
						
							|  |  |  |         Bucket=bucket_name, | 
					
						
							|  |  |  |         CreateBucketConfiguration={"LocationConstraint": "us-west-1"}, | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2019-05-25 12:19:00 +02:00
										 |  |  |     resp = s3.put_bucket_accelerate_configuration( | 
					
						
							|  |  |  |         Bucket=bucket_name, AccelerateConfiguration={"Status": "Suspended"} | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2019-10-03 18:00:07 -07:00
										 |  |  |     resp.keys().should.have.length_of( | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         1 | 
					
						
							| 
									
										
										
										
											2019-10-03 18:00:07 -07:00
										 |  |  |     )  # Response contains nothing (only HTTP headers) | 
					
						
							| 
									
										
										
										
											2019-05-25 12:19:00 +02:00
										 |  |  |     resp = s3.get_bucket_accelerate_configuration(Bucket=bucket_name) | 
					
						
							|  |  |  |     resp.shouldnt.have.key("Status") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-23 17:16:20 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-25 12:19:00 +02:00
										 |  |  | @mock_s3 | 
					
						
							|  |  |  | def test_accelerate_configuration_status_validation(): | 
					
						
							|  |  |  |     bucket_name = "some_bucket" | 
					
						
							| 
									
										
										
										
											2020-02-02 10:36:51 +00:00
										 |  |  |     s3 = boto3.client("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							| 
									
										
										
										
											2019-05-25 12:19:00 +02:00
										 |  |  |     s3.create_bucket(Bucket=bucket_name) | 
					
						
							| 
									
										
										
										
											2020-10-06 07:54:49 +02:00
										 |  |  |     with pytest.raises(ClientError) as exc: | 
					
						
							| 
									
										
										
										
											2019-05-25 12:19:00 +02:00
										 |  |  |         s3.put_bucket_accelerate_configuration( | 
					
						
							|  |  |  |             Bucket=bucket_name, AccelerateConfiguration={"Status": "bad_status"} | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2020-10-06 08:04:09 +02:00
										 |  |  |     exc.value.response["Error"]["Code"].should.equal("MalformedXML") | 
					
						
							| 
									
										
										
										
											2019-05-25 12:19:00 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-23 17:16:20 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-25 12:19:00 +02:00
										 |  |  | @mock_s3 | 
					
						
							|  |  |  | def test_accelerate_configuration_is_not_supported_when_bucket_name_has_dots(): | 
					
						
							|  |  |  |     bucket_name = "some.bucket.with.dots" | 
					
						
							| 
									
										
										
										
											2020-02-02 10:36:51 +00:00
										 |  |  |     s3 = boto3.client("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							| 
									
										
										
										
											2019-05-25 12:19:00 +02:00
										 |  |  |     s3.create_bucket(Bucket=bucket_name) | 
					
						
							| 
									
										
										
										
											2020-10-06 07:54:49 +02:00
										 |  |  |     with pytest.raises(ClientError) as exc: | 
					
						
							| 
									
										
										
										
											2019-05-25 12:19:00 +02:00
										 |  |  |         s3.put_bucket_accelerate_configuration( | 
					
						
							|  |  |  |             Bucket=bucket_name, AccelerateConfiguration={"Status": "Enabled"} | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2020-10-06 08:04:09 +02:00
										 |  |  |     exc.value.response["Error"]["Code"].should.equal("InvalidRequest") | 
					
						
							| 
									
										
										
										
											2019-08-28 16:17:45 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-23 17:16:20 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-28 16:17:45 +02:00
										 |  |  | def store_and_read_back_a_key(key): | 
					
						
							| 
									
										
										
										
											2020-02-02 10:36:51 +00:00
										 |  |  |     s3 = boto3.client("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							| 
									
										
										
										
											2019-08-28 16:17:45 +02:00
										 |  |  |     bucket_name = "mybucket" | 
					
						
							|  |  |  |     body = b"Some body" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     s3.create_bucket(Bucket=bucket_name) | 
					
						
							|  |  |  |     s3.put_object(Bucket=bucket_name, Key=key, Body=body) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     response = s3.get_object(Bucket=bucket_name, Key=key) | 
					
						
							|  |  |  |     response["Body"].read().should.equal(body) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-23 17:16:20 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-28 16:17:45 +02:00
										 |  |  | @mock_s3 | 
					
						
							|  |  |  | def test_paths_with_leading_slashes_work(): | 
					
						
							|  |  |  |     store_and_read_back_a_key("/a-key") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-23 17:16:20 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-28 16:17:45 +02:00
										 |  |  | @mock_s3 | 
					
						
							|  |  |  | def test_root_dir_with_empty_name_works(): | 
					
						
							| 
									
										
										
										
											2020-05-01 13:50:11 +01:00
										 |  |  |     if settings.TEST_SERVER_MODE: | 
					
						
							| 
									
										
										
										
											2019-08-28 16:17:45 +02:00
										 |  |  |         raise SkipTest("Does not work in server mode due to error in Workzeug") | 
					
						
							|  |  |  |     store_and_read_back_a_key("/") | 
					
						
							| 
									
										
										
										
											2019-09-24 15:22:25 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-11 15:54:01 +00:00
										 |  |  | @pytest.mark.parametrize("bucket_name", ["mybucket", "my.bucket"]) | 
					
						
							| 
									
										
										
										
											2020-04-20 20:54:31 +02:00
										 |  |  | @mock_s3 | 
					
						
							|  |  |  | def test_leading_slashes_not_removed(bucket_name): | 
					
						
							|  |  |  |     """Make sure that leading slashes are not removed internally.""" | 
					
						
							|  |  |  |     s3 = boto3.client("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							|  |  |  |     s3.create_bucket(Bucket=bucket_name) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-25 15:10:23 +02:00
										 |  |  |     uploaded_key = "/key" | 
					
						
							|  |  |  |     invalid_key_1 = "key" | 
					
						
							|  |  |  |     invalid_key_2 = "//key" | 
					
						
							| 
									
										
										
										
											2020-04-20 20:54:31 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-25 15:10:23 +02:00
										 |  |  |     s3.put_object(Bucket=bucket_name, Key=uploaded_key, Body=b"Some body") | 
					
						
							| 
									
										
										
										
											2020-04-20 20:54:31 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-06 07:54:49 +02:00
										 |  |  |     with pytest.raises(ClientError) as e: | 
					
						
							| 
									
										
										
										
											2020-04-20 20:54:31 +02:00
										 |  |  |         s3.get_object(Bucket=bucket_name, Key=invalid_key_1) | 
					
						
							| 
									
										
										
										
											2020-10-06 08:04:09 +02:00
										 |  |  |     e.value.response["Error"]["Code"].should.equal("NoSuchKey") | 
					
						
							| 
									
										
										
										
											2020-04-20 20:54:31 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-06 07:54:49 +02:00
										 |  |  |     with pytest.raises(ClientError) as e: | 
					
						
							| 
									
										
										
										
											2020-04-20 20:54:31 +02:00
										 |  |  |         s3.get_object(Bucket=bucket_name, Key=invalid_key_2) | 
					
						
							| 
									
										
										
										
											2020-10-06 08:04:09 +02:00
										 |  |  |     e.value.response["Error"]["Code"].should.equal("NoSuchKey") | 
					
						
							| 
									
										
										
										
											2020-04-20 20:54:31 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-11 15:55:37 +00:00
										 |  |  | @pytest.mark.parametrize( | 
					
						
							|  |  |  |     "key", ["foo/bar/baz", "foo", "foo/run_dt%3D2019-01-01%252012%253A30%253A00"] | 
					
						
							| 
									
										
										
										
											2019-09-24 15:22:25 -05:00
										 |  |  | ) | 
					
						
							|  |  |  | @mock_s3 | 
					
						
							|  |  |  | def test_delete_objects_with_url_encoded_key(key): | 
					
						
							| 
									
										
										
										
											2020-02-02 10:36:51 +00:00
										 |  |  |     s3 = boto3.client("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							| 
									
										
										
										
											2019-09-24 15:22:25 -05:00
										 |  |  |     bucket_name = "mybucket" | 
					
						
							|  |  |  |     body = b"Some body" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     s3.create_bucket(Bucket=bucket_name) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def put_object(): | 
					
						
							|  |  |  |         s3.put_object(Bucket=bucket_name, Key=key, Body=body) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def assert_deleted(): | 
					
						
							| 
									
										
										
										
											2020-10-06 07:54:49 +02:00
										 |  |  |         with pytest.raises(ClientError) as e: | 
					
						
							| 
									
										
										
										
											2019-09-24 15:22:25 -05:00
										 |  |  |             s3.get_object(Bucket=bucket_name, Key=key) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-06 08:04:09 +02:00
										 |  |  |         e.value.response["Error"]["Code"].should.equal("NoSuchKey") | 
					
						
							| 
									
										
										
										
											2019-09-24 15:22:25 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     put_object() | 
					
						
							|  |  |  |     s3.delete_object(Bucket=bucket_name, Key=key) | 
					
						
							|  |  |  |     assert_deleted() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     put_object() | 
					
						
							|  |  |  |     s3.delete_objects(Bucket=bucket_name, Delete={"Objects": [{"Key": key}]}) | 
					
						
							|  |  |  |     assert_deleted() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-23 17:16:20 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-25 10:26:03 +01:00
										 |  |  | @mock_s3 | 
					
						
							|  |  |  | def test_delete_objects_unknown_key(): | 
					
						
							|  |  |  |     bucket_name = "test-moto-issue-1581" | 
					
						
							|  |  |  |     client = boto3.client("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							|  |  |  |     client.create_bucket(Bucket=bucket_name) | 
					
						
							|  |  |  |     client.put_object(Bucket=bucket_name, Key="file1", Body="body") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     s = client.delete_objects( | 
					
						
							|  |  |  |         Bucket=bucket_name, Delete={"Objects": [{"Key": "file1"}, {"Key": "file2"}]} | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     s["Deleted"].should.have.length_of(2) | 
					
						
							|  |  |  |     s["Deleted"].should.contain({"Key": "file1"}) | 
					
						
							|  |  |  |     s["Deleted"].should.contain({"Key": "file2"}) | 
					
						
							|  |  |  |     client.delete_bucket(Bucket=bucket_name) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-09 17:38:26 -08:00
										 |  |  | @mock_s3 | 
					
						
							|  |  |  | @mock_config | 
					
						
							|  |  |  | def test_public_access_block(): | 
					
						
							| 
									
										
										
										
											2020-02-02 10:36:51 +00:00
										 |  |  |     client = boto3.client("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							| 
									
										
										
										
											2019-12-09 17:38:26 -08:00
										 |  |  |     client.create_bucket(Bucket="mybucket") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Try to get the public access block (should not exist by default) | 
					
						
							| 
									
										
										
										
											2020-10-06 07:54:49 +02:00
										 |  |  |     with pytest.raises(ClientError) as ce: | 
					
						
							| 
									
										
										
										
											2019-12-09 17:38:26 -08:00
										 |  |  |         client.get_public_access_block(Bucket="mybucket") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-06 08:46:05 +02:00
										 |  |  |     assert ce.value.response["Error"]["Code"] == "NoSuchPublicAccessBlockConfiguration" | 
					
						
							| 
									
										
										
										
											2019-12-09 17:38:26 -08:00
										 |  |  |     assert ( | 
					
						
							| 
									
										
										
										
											2020-10-06 08:04:09 +02:00
										 |  |  |         ce.value.response["Error"]["Message"] | 
					
						
							| 
									
										
										
										
											2019-12-09 17:38:26 -08:00
										 |  |  |         == "The public access block configuration was not found" | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2020-10-06 08:04:09 +02:00
										 |  |  |     assert ce.value.response["ResponseMetadata"]["HTTPStatusCode"] == 404 | 
					
						
							| 
									
										
										
										
											2019-12-09 17:38:26 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # Put a public block in place: | 
					
						
							|  |  |  |     test_map = { | 
					
						
							|  |  |  |         "BlockPublicAcls": False, | 
					
						
							|  |  |  |         "IgnorePublicAcls": False, | 
					
						
							|  |  |  |         "BlockPublicPolicy": False, | 
					
						
							|  |  |  |         "RestrictPublicBuckets": False, | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for field in test_map.keys(): | 
					
						
							|  |  |  |         # Toggle: | 
					
						
							|  |  |  |         test_map[field] = True | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         client.put_public_access_block( | 
					
						
							|  |  |  |             Bucket="mybucket", PublicAccessBlockConfiguration=test_map | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # Test: | 
					
						
							|  |  |  |         assert ( | 
					
						
							|  |  |  |             test_map | 
					
						
							|  |  |  |             == client.get_public_access_block(Bucket="mybucket")[ | 
					
						
							|  |  |  |                 "PublicAccessBlockConfiguration" | 
					
						
							|  |  |  |             ] | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Assume missing values are default False: | 
					
						
							|  |  |  |     client.put_public_access_block( | 
					
						
							|  |  |  |         Bucket="mybucket", PublicAccessBlockConfiguration={"BlockPublicAcls": True} | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     assert client.get_public_access_block(Bucket="mybucket")[ | 
					
						
							|  |  |  |         "PublicAccessBlockConfiguration" | 
					
						
							|  |  |  |     ] == { | 
					
						
							|  |  |  |         "BlockPublicAcls": True, | 
					
						
							|  |  |  |         "IgnorePublicAcls": False, | 
					
						
							|  |  |  |         "BlockPublicPolicy": False, | 
					
						
							|  |  |  |         "RestrictPublicBuckets": False, | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Test with a blank PublicAccessBlockConfiguration: | 
					
						
							| 
									
										
										
										
											2020-10-06 07:54:49 +02:00
										 |  |  |     with pytest.raises(ClientError) as ce: | 
					
						
							| 
									
										
										
										
											2019-12-09 17:38:26 -08:00
										 |  |  |         client.put_public_access_block( | 
					
						
							|  |  |  |             Bucket="mybucket", PublicAccessBlockConfiguration={} | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-06 08:04:09 +02:00
										 |  |  |     assert ce.value.response["Error"]["Code"] == "InvalidRequest" | 
					
						
							| 
									
										
										
										
											2019-12-09 17:38:26 -08:00
										 |  |  |     assert ( | 
					
						
							| 
									
										
										
										
											2020-10-06 08:04:09 +02:00
										 |  |  |         ce.value.response["Error"]["Message"] | 
					
						
							| 
									
										
										
										
											2019-12-09 17:38:26 -08:00
										 |  |  |         == "Must specify at least one configuration." | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2020-10-06 08:04:09 +02:00
										 |  |  |     assert ce.value.response["ResponseMetadata"]["HTTPStatusCode"] == 400 | 
					
						
							| 
									
										
										
										
											2019-12-09 17:38:26 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # Test that things work with AWS Config: | 
					
						
							| 
									
										
										
										
											2020-02-02 10:36:51 +00:00
										 |  |  |     config_client = boto3.client("config", region_name=DEFAULT_REGION_NAME) | 
					
						
							| 
									
										
										
										
											2019-12-09 17:38:26 -08:00
										 |  |  |     result = config_client.get_resource_config_history( | 
					
						
							|  |  |  |         resourceType="AWS::S3::Bucket", resourceId="mybucket" | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     pub_block_config = json.loads( | 
					
						
							|  |  |  |         result["configurationItems"][0]["supplementaryConfiguration"][ | 
					
						
							|  |  |  |             "PublicAccessBlockConfiguration" | 
					
						
							|  |  |  |         ] | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     assert pub_block_config == { | 
					
						
							|  |  |  |         "blockPublicAcls": True, | 
					
						
							|  |  |  |         "ignorePublicAcls": False, | 
					
						
							|  |  |  |         "blockPublicPolicy": False, | 
					
						
							|  |  |  |         "restrictPublicBuckets": False, | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Delete: | 
					
						
							|  |  |  |     client.delete_public_access_block(Bucket="mybucket") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-06 07:54:49 +02:00
										 |  |  |     with pytest.raises(ClientError) as ce: | 
					
						
							| 
									
										
										
										
											2019-12-09 17:38:26 -08:00
										 |  |  |         client.get_public_access_block(Bucket="mybucket") | 
					
						
							| 
									
										
										
										
											2020-10-06 08:46:05 +02:00
										 |  |  |     assert ce.value.response["Error"]["Code"] == "NoSuchPublicAccessBlockConfiguration" | 
					
						
							| 
									
										
										
										
											2019-12-09 17:38:26 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-29 15:22:29 -05:00
										 |  |  | @mock_s3 | 
					
						
							|  |  |  | def test_creating_presigned_post(): | 
					
						
							| 
									
										
										
										
											2020-04-21 21:43:32 -05:00
										 |  |  |     bucket = "presigned-test" | 
					
						
							|  |  |  |     s3 = boto3.client("s3", region_name="us-east-1") | 
					
						
							| 
									
										
										
										
											2019-05-29 15:22:29 -05:00
										 |  |  |     s3.create_bucket(Bucket=bucket) | 
					
						
							| 
									
										
										
										
											2020-04-21 21:43:32 -05:00
										 |  |  |     success_url = "http://localhost/completed" | 
					
						
							|  |  |  |     fdata = b"test data\n" | 
					
						
							| 
									
										
										
										
											2019-05-29 15:22:29 -05:00
										 |  |  |     file_uid = uuid.uuid4() | 
					
						
							|  |  |  |     conditions = [ | 
					
						
							| 
									
										
										
										
											2020-04-21 21:43:32 -05:00
										 |  |  |         {"Content-Type": "text/plain"}, | 
					
						
							| 
									
										
										
										
											2019-05-29 15:22:29 -05:00
										 |  |  |         {"x-amz-server-side-encryption": "AES256"}, | 
					
						
							| 
									
										
										
										
											2020-04-21 21:43:32 -05:00
										 |  |  |         {"success_action_redirect": success_url}, | 
					
						
							| 
									
										
										
										
											2019-05-29 15:22:29 -05:00
										 |  |  |     ] | 
					
						
							|  |  |  |     conditions.append(["content-length-range", 1, 30]) | 
					
						
							| 
									
										
										
										
											2021-02-10 02:06:03 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-17 21:41:08 -01:00
										 |  |  |     real_key = f"{file_uid}.txt" | 
					
						
							| 
									
										
										
										
											2019-05-29 15:22:29 -05:00
										 |  |  |     data = s3.generate_presigned_post( | 
					
						
							|  |  |  |         Bucket=bucket, | 
					
						
							| 
									
										
										
										
											2021-02-10 02:06:03 -07:00
										 |  |  |         Key=real_key, | 
					
						
							| 
									
										
										
										
											2019-05-29 15:22:29 -05:00
										 |  |  |         Fields={ | 
					
						
							| 
									
										
										
										
											2020-04-21 21:43:32 -05:00
										 |  |  |             "content-type": "text/plain", | 
					
						
							|  |  |  |             "success_action_redirect": success_url, | 
					
						
							|  |  |  |             "x-amz-server-side-encryption": "AES256", | 
					
						
							| 
									
										
										
										
											2019-05-29 15:22:29 -05:00
										 |  |  |         }, | 
					
						
							|  |  |  |         Conditions=conditions, | 
					
						
							|  |  |  |         ExpiresIn=1000, | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2020-04-21 21:43:32 -05:00
										 |  |  |     resp = requests.post( | 
					
						
							|  |  |  |         data["url"], data=data["fields"], files={"file": fdata}, allow_redirects=False | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2019-05-29 15:22:29 -05:00
										 |  |  |     assert resp.status_code == 303 | 
					
						
							| 
									
										
										
										
											2021-02-10 02:06:03 -07:00
										 |  |  |     redirect = resp.headers["Location"] | 
					
						
							|  |  |  |     assert redirect.startswith(success_url) | 
					
						
							|  |  |  |     parts = urlparse(redirect) | 
					
						
							|  |  |  |     args = parse_qs(parts.query) | 
					
						
							|  |  |  |     assert args["key"][0] == real_key | 
					
						
							|  |  |  |     assert args["bucket"][0] == bucket | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     assert s3.get_object(Bucket=bucket, Key=real_key)["Body"].read() == fdata | 
					
						
							| 
									
										
										
										
											2020-05-27 12:21:03 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-12 13:33:46 +01:00
										 |  |  | @mock_s3 | 
					
						
							|  |  |  | def test_presigned_put_url_with_approved_headers(): | 
					
						
							|  |  |  |     bucket = str(uuid.uuid4()) | 
					
						
							|  |  |  |     key = "file.txt" | 
					
						
							| 
									
										
										
										
											2020-07-12 18:29:10 +01:00
										 |  |  |     content = b"filecontent" | 
					
						
							| 
									
										
										
										
											2020-07-12 13:33:46 +01:00
										 |  |  |     expected_contenttype = "app/sth" | 
					
						
							|  |  |  |     conn = boto3.resource("s3", region_name="us-east-1") | 
					
						
							|  |  |  |     conn.create_bucket(Bucket=bucket) | 
					
						
							|  |  |  |     s3 = boto3.client("s3", region_name="us-east-1") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Create a pre-signed url with some metadata. | 
					
						
							|  |  |  |     url = s3.generate_presigned_url( | 
					
						
							|  |  |  |         ClientMethod="put_object", | 
					
						
							|  |  |  |         Params={"Bucket": bucket, "Key": key, "ContentType": expected_contenttype}, | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Verify S3 throws an error when the header is not provided | 
					
						
							| 
									
										
										
										
											2020-07-12 18:29:10 +01:00
										 |  |  |     response = requests.put(url, data=content) | 
					
						
							| 
									
										
										
										
											2020-07-12 13:33:46 +01:00
										 |  |  |     response.status_code.should.equal(403) | 
					
						
							| 
									
										
										
										
											2020-07-12 18:29:10 +01:00
										 |  |  |     str(response.content).should.contain("<Code>SignatureDoesNotMatch</Code>") | 
					
						
							|  |  |  |     str(response.content).should.contain( | 
					
						
							| 
									
										
										
										
											2020-07-12 13:33:46 +01:00
										 |  |  |         "<Message>The request signature we calculated does not match the signature you provided. Check your key and signing method.</Message>" | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Verify S3 throws an error when the header has the wrong value | 
					
						
							|  |  |  |     response = requests.put( | 
					
						
							| 
									
										
										
										
											2020-07-12 18:29:10 +01:00
										 |  |  |         url, data=content, headers={"Content-Type": "application/unknown"} | 
					
						
							| 
									
										
										
										
											2020-07-12 13:33:46 +01:00
										 |  |  |     ) | 
					
						
							|  |  |  |     response.status_code.should.equal(403) | 
					
						
							| 
									
										
										
										
											2020-07-12 18:29:10 +01:00
										 |  |  |     str(response.content).should.contain("<Code>SignatureDoesNotMatch</Code>") | 
					
						
							|  |  |  |     str(response.content).should.contain( | 
					
						
							| 
									
										
										
										
											2020-07-12 13:33:46 +01:00
										 |  |  |         "<Message>The request signature we calculated does not match the signature you provided. Check your key and signing method.</Message>" | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Verify S3 uploads correctly when providing the meta data | 
					
						
							|  |  |  |     response = requests.put( | 
					
						
							| 
									
										
										
										
											2020-07-12 18:29:10 +01:00
										 |  |  |         url, data=content, headers={"Content-Type": expected_contenttype} | 
					
						
							| 
									
										
										
										
											2020-07-12 13:33:46 +01:00
										 |  |  |     ) | 
					
						
							|  |  |  |     response.status_code.should.equal(200) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Assert the object exists | 
					
						
							|  |  |  |     obj = s3.get_object(Bucket=bucket, Key=key) | 
					
						
							|  |  |  |     obj["ContentType"].should.equal(expected_contenttype) | 
					
						
							|  |  |  |     obj["ContentLength"].should.equal(11) | 
					
						
							| 
									
										
										
										
											2020-07-12 18:29:10 +01:00
										 |  |  |     obj["Body"].read().should.equal(content) | 
					
						
							| 
									
										
										
										
											2020-07-12 13:33:46 +01:00
										 |  |  |     obj["Metadata"].should.equal({}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     s3.delete_object(Bucket=bucket, Key=key) | 
					
						
							|  |  |  |     s3.delete_bucket(Bucket=bucket) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_s3 | 
					
						
							|  |  |  | def test_presigned_put_url_with_custom_headers(): | 
					
						
							|  |  |  |     bucket = str(uuid.uuid4()) | 
					
						
							|  |  |  |     key = "file.txt" | 
					
						
							| 
									
										
										
										
											2020-07-12 18:29:10 +01:00
										 |  |  |     content = b"filecontent" | 
					
						
							| 
									
										
										
										
											2020-07-12 13:33:46 +01:00
										 |  |  |     conn = boto3.resource("s3", region_name="us-east-1") | 
					
						
							|  |  |  |     conn.create_bucket(Bucket=bucket) | 
					
						
							|  |  |  |     s3 = boto3.client("s3", region_name="us-east-1") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Create a pre-signed url with some metadata. | 
					
						
							|  |  |  |     url = s3.generate_presigned_url( | 
					
						
							|  |  |  |         ClientMethod="put_object", | 
					
						
							|  |  |  |         Params={"Bucket": bucket, "Key": key, "Metadata": {"venue": "123"}}, | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Verify S3 uploads correctly when providing the meta data | 
					
						
							| 
									
										
										
										
											2020-07-12 18:29:10 +01:00
										 |  |  |     response = requests.put(url, data=content) | 
					
						
							| 
									
										
										
										
											2020-07-12 13:33:46 +01:00
										 |  |  |     response.status_code.should.equal(200) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Assert the object exists | 
					
						
							|  |  |  |     obj = s3.get_object(Bucket=bucket, Key=key) | 
					
						
							|  |  |  |     obj["ContentLength"].should.equal(11) | 
					
						
							| 
									
										
										
										
											2020-07-12 18:29:10 +01:00
										 |  |  |     obj["Body"].read().should.equal(content) | 
					
						
							| 
									
										
										
										
											2020-07-12 13:33:46 +01:00
										 |  |  |     obj["Metadata"].should.equal({"venue": "123"}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     s3.delete_object(Bucket=bucket, Key=key) | 
					
						
							|  |  |  |     s3.delete_bucket(Bucket=bucket) | 
					
						
							| 
									
										
										
										
											2020-10-28 14:22:18 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_s3 | 
					
						
							|  |  |  | def test_request_partial_content_should_contain_content_length(): | 
					
						
							|  |  |  |     bucket = "bucket" | 
					
						
							|  |  |  |     object_key = "key" | 
					
						
							| 
									
										
										
										
											2021-08-19 01:25:33 +06:00
										 |  |  |     s3 = boto3.resource("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							| 
									
										
										
										
											2020-10-28 14:22:18 +00:00
										 |  |  |     s3.create_bucket(Bucket=bucket) | 
					
						
							|  |  |  |     s3.Object(bucket, object_key).put(Body="some text") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     file = s3.Object(bucket, object_key) | 
					
						
							|  |  |  |     response = file.get(Range="bytes=0-1024") | 
					
						
							|  |  |  |     response["ContentLength"].should.equal(9) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_s3 | 
					
						
							|  |  |  | def test_request_partial_content_should_contain_actual_content_length(): | 
					
						
							|  |  |  |     bucket = "bucket" | 
					
						
							|  |  |  |     object_key = "key" | 
					
						
							| 
									
										
										
										
											2021-08-19 01:25:33 +06:00
										 |  |  |     s3 = boto3.resource("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							| 
									
										
										
										
											2020-10-28 14:22:18 +00:00
										 |  |  |     s3.create_bucket(Bucket=bucket) | 
					
						
							|  |  |  |     s3.Object(bucket, object_key).put(Body="some text") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     file = s3.Object(bucket, object_key) | 
					
						
							|  |  |  |     requested_range = "bytes=1024-" | 
					
						
							|  |  |  |     try: | 
					
						
							|  |  |  |         file.get(Range=requested_range) | 
					
						
							|  |  |  |     except botocore.client.ClientError as e: | 
					
						
							|  |  |  |         e.response["Error"]["Code"].should.equal("InvalidRange") | 
					
						
							|  |  |  |         e.response["Error"]["Message"].should.equal( | 
					
						
							|  |  |  |             "The requested range is not satisfiable" | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         e.response["Error"]["ActualObjectSize"].should.equal("9") | 
					
						
							|  |  |  |         e.response["Error"]["RangeRequested"].should.equal(requested_range) | 
					
						
							| 
									
										
										
										
											2021-01-13 10:00:18 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-13 16:06:09 +00:00
										 |  |  | @mock_s3 | 
					
						
							|  |  |  | def test_get_unknown_version_should_throw_specific_error(): | 
					
						
							|  |  |  |     bucket_name = "my_bucket" | 
					
						
							|  |  |  |     object_key = "hello.txt" | 
					
						
							|  |  |  |     s3 = boto3.resource("s3", region_name="us-east-1") | 
					
						
							|  |  |  |     client = boto3.client("s3", region_name="us-east-1") | 
					
						
							|  |  |  |     bucket = s3.create_bucket(Bucket=bucket_name) | 
					
						
							|  |  |  |     bucket.Versioning().enable() | 
					
						
							|  |  |  |     content = "some text" | 
					
						
							|  |  |  |     s3.Object(bucket_name, object_key).put(Body=content) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     with pytest.raises(ClientError) as e: | 
					
						
							|  |  |  |         client.get_object(Bucket=bucket_name, Key=object_key, VersionId="unknown") | 
					
						
							| 
									
										
										
										
											2021-04-30 04:36:08 -07:00
										 |  |  |     e.value.response["Error"]["Code"].should.equal("NoSuchVersion") | 
					
						
							|  |  |  |     e.value.response["Error"]["Message"].should.equal( | 
					
						
							|  |  |  |         "The specified version does not exist." | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2021-01-13 16:06:09 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-13 10:00:18 +00:00
										 |  |  | @mock_s3 | 
					
						
							|  |  |  | def test_request_partial_content_without_specifying_range_should_return_full_object(): | 
					
						
							|  |  |  |     bucket = "bucket" | 
					
						
							|  |  |  |     object_key = "key" | 
					
						
							|  |  |  |     s3 = boto3.resource("s3", region_name="us-east-1") | 
					
						
							|  |  |  |     s3.create_bucket(Bucket=bucket) | 
					
						
							|  |  |  |     s3.Object(bucket, object_key).put(Body="some text that goes a long way") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     file = s3.Object(bucket, object_key) | 
					
						
							|  |  |  |     response = file.get(Range="") | 
					
						
							|  |  |  |     response["ContentLength"].should.equal(30) | 
					
						
							| 
									
										
										
										
											2021-01-18 23:47:13 +05:30
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_s3 | 
					
						
							|  |  |  | def test_object_headers(): | 
					
						
							|  |  |  |     bucket = "my-bucket" | 
					
						
							| 
									
										
										
										
											2021-08-19 01:25:33 +06:00
										 |  |  |     s3 = boto3.client("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							| 
									
										
										
										
											2021-01-18 23:47:13 +05:30
										 |  |  |     s3.create_bucket(Bucket=bucket) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     res = s3.put_object( | 
					
						
							|  |  |  |         Bucket=bucket, | 
					
						
							|  |  |  |         Body=b"test", | 
					
						
							|  |  |  |         Key="file.txt", | 
					
						
							|  |  |  |         ServerSideEncryption="aws:kms", | 
					
						
							|  |  |  |         SSEKMSKeyId="test", | 
					
						
							|  |  |  |         BucketKeyEnabled=True, | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     res.should.have.key("ETag") | 
					
						
							|  |  |  |     res.should.have.key("ServerSideEncryption") | 
					
						
							|  |  |  |     res.should.have.key("SSEKMSKeyId") | 
					
						
							|  |  |  |     res.should.have.key("BucketKeyEnabled") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     res = s3.get_object(Bucket=bucket, Key="file.txt") | 
					
						
							|  |  |  |     res.should.have.key("ETag") | 
					
						
							|  |  |  |     res.should.have.key("ServerSideEncryption") | 
					
						
							|  |  |  |     res.should.have.key("SSEKMSKeyId") | 
					
						
							|  |  |  |     res.should.have.key("BucketKeyEnabled") | 
					
						
							| 
									
										
										
										
											2021-06-28 16:22:08 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-28 06:10:16 +01:00
										 |  |  | if settings.TEST_SERVER_MODE: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @mock_s3 | 
					
						
							|  |  |  |     def test_upload_data_without_content_type(): | 
					
						
							|  |  |  |         bucket = "mybucket" | 
					
						
							|  |  |  |         s3 = boto3.client("s3") | 
					
						
							|  |  |  |         s3.create_bucket(Bucket=bucket) | 
					
						
							|  |  |  |         data_input = b"some data 123 321" | 
					
						
							|  |  |  |         req = requests.put("http://localhost:5000/mybucket/test.txt", data=data_input) | 
					
						
							|  |  |  |         req.status_code.should.equal(200) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         res = s3.get_object(Bucket=bucket, Key="test.txt") | 
					
						
							|  |  |  |         data = res["Body"].read() | 
					
						
							|  |  |  |         assert data == data_input | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-28 16:22:08 +01:00
										 |  |  | @mock_s3 | 
					
						
							| 
									
										
										
										
											2022-11-22 22:41:02 -01:00
										 |  |  | @pytest.mark.parametrize( | 
					
						
							|  |  |  |     "prefix", ["file", "file+else", "file&another", "file another"] | 
					
						
							|  |  |  | ) | 
					
						
							| 
									
										
										
										
											2022-05-05 11:06:31 +00:00
										 |  |  | def test_get_object_versions_with_prefix(prefix): | 
					
						
							| 
									
										
										
										
											2021-06-28 16:22:08 +01:00
										 |  |  |     bucket_name = "testbucket-3113" | 
					
						
							| 
									
										
										
										
											2021-08-19 01:25:33 +06:00
										 |  |  |     s3_resource = boto3.resource("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							|  |  |  |     s3_client = boto3.client("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							| 
									
										
										
										
											2021-06-28 16:22:08 +01:00
										 |  |  |     s3_client.create_bucket(Bucket=bucket_name) | 
					
						
							|  |  |  |     bucket_versioning = s3_resource.BucketVersioning(bucket_name) | 
					
						
							|  |  |  |     bucket_versioning.enable() | 
					
						
							| 
									
										
										
										
											2022-05-05 11:06:31 +00:00
										 |  |  |     s3_client.put_object(Bucket=bucket_name, Body=b"test", Key=f"{prefix}.txt") | 
					
						
							|  |  |  |     s3_client.put_object(Bucket=bucket_name, Body=b"test", Key=f"{prefix}.txt") | 
					
						
							|  |  |  |     s3_client.put_object(Bucket=bucket_name, Body=b"alttest", Key=f"alt{prefix}.txt") | 
					
						
							|  |  |  |     s3_client.put_object(Bucket=bucket_name, Body=b"test", Key=f"{prefix}.txt") | 
					
						
							| 
									
										
										
										
											2021-06-28 16:22:08 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-05 11:06:31 +00:00
										 |  |  |     versions = s3_client.list_object_versions(Bucket=bucket_name, Prefix=prefix) | 
					
						
							| 
									
										
										
										
											2021-06-28 16:22:08 +01:00
										 |  |  |     versions["Versions"].should.have.length_of(3) | 
					
						
							| 
									
										
										
										
											2022-05-05 11:06:31 +00:00
										 |  |  |     versions["Prefix"].should.equal(prefix) | 
					
						
							| 
									
										
										
										
											2021-09-01 16:30:01 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @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) | 
					
						
							| 
									
										
										
										
											2021-10-09 10:12:26 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_s3 | 
					
						
							|  |  |  | def test_delete_objects_with_empty_keyname(): | 
					
						
							|  |  |  |     client = boto3.client("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							|  |  |  |     resource = boto3.resource("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							|  |  |  |     bucket_name = "testbucket-4077" | 
					
						
							|  |  |  |     bucket = resource.create_bucket(Bucket=bucket_name) | 
					
						
							|  |  |  |     key_name = " " | 
					
						
							|  |  |  |     bucket.put_object(Key=key_name, Body=b"") | 
					
						
							|  |  |  |     client.list_objects(Bucket=bucket_name).should.have.key("Contents").length_of(1) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     bucket.delete_objects(Delete={"Objects": [{"Key": key_name}]}) | 
					
						
							|  |  |  |     client.list_objects(Bucket=bucket_name).shouldnt.have.key("Contents") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     bucket.put_object(Key=key_name, Body=b"") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     client.delete_object(Bucket=bucket_name, Key=key_name) | 
					
						
							|  |  |  |     client.list_objects(Bucket=bucket_name).shouldnt.have.key("Contents") | 
					
						
							| 
									
										
										
										
											2021-10-19 16:46:23 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_s3 | 
					
						
							|  |  |  | def test_head_object_should_return_default_content_type(): | 
					
						
							|  |  |  |     s3 = boto3.resource("s3", region_name="us-east-1") | 
					
						
							|  |  |  |     s3.create_bucket(Bucket="testbucket") | 
					
						
							|  |  |  |     s3.Bucket("testbucket").upload_fileobj(BytesIO(b"foobar"), Key="testobject") | 
					
						
							|  |  |  |     s3_client = boto3.client("s3", region_name="us-east-1") | 
					
						
							|  |  |  |     resp = s3_client.head_object(Bucket="testbucket", Key="testobject") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     resp["ContentType"].should.equal("binary/octet-stream") | 
					
						
							|  |  |  |     resp["ResponseMetadata"]["HTTPHeaders"]["content-type"].should.equal( | 
					
						
							|  |  |  |         "binary/octet-stream" | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     s3.Object("testbucket", "testobject").content_type.should.equal( | 
					
						
							|  |  |  |         "binary/octet-stream" | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2021-10-30 11:49:42 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_s3 | 
					
						
							|  |  |  | def test_request_partial_content_should_contain_all_metadata(): | 
					
						
							| 
									
										
										
										
											2023-01-07 11:35:14 +00:00
										 |  |  |     # github.com/getmoto/moto/issues/4203 | 
					
						
							| 
									
										
										
										
											2021-10-30 11:49:42 +02:00
										 |  |  |     bucket = "bucket" | 
					
						
							|  |  |  |     object_key = "key" | 
					
						
							|  |  |  |     body = "some text" | 
					
						
							|  |  |  |     query_range = "0-3" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     s3 = boto3.resource("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							|  |  |  |     s3.create_bucket(Bucket=bucket) | 
					
						
							|  |  |  |     obj = boto3.resource("s3").Object(bucket, object_key) | 
					
						
							|  |  |  |     obj.put(Body=body) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-17 21:41:08 -01:00
										 |  |  |     response = obj.get(Range=f"bytes={query_range}") | 
					
						
							| 
									
										
										
										
											2021-10-30 11:49:42 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     assert response["ETag"] == obj.e_tag | 
					
						
							|  |  |  |     assert response["LastModified"] == obj.last_modified | 
					
						
							|  |  |  |     assert response["ContentLength"] == 4 | 
					
						
							| 
									
										
										
										
											2022-11-17 21:41:08 -01:00
										 |  |  |     assert response["ContentRange"] == f"bytes {query_range}/{len(body)}" | 
					
						
							| 
									
										
										
										
											2021-11-18 20:57:12 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-26 16:05:48 -05:00
										 |  |  | @mock_s3 | 
					
						
							|  |  |  | def test_head_versioned_key_in_not_versioned_bucket(): | 
					
						
							|  |  |  |     client = boto3.client("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							|  |  |  |     client.create_bucket(Bucket="simple-bucked") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     with pytest.raises(ClientError) as ex: | 
					
						
							|  |  |  |         client.head_object( | 
					
						
							|  |  |  |             Bucket="simple-bucked", Key="file.txt", VersionId="noVersion" | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     response = ex.value.response | 
					
						
							|  |  |  |     assert response["Error"]["Code"] == "400" | 
					
						
							| 
									
										
										
										
											2022-06-17 05:21:06 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_s3 | 
					
						
							|  |  |  | def test_prefix_encoding(): | 
					
						
							|  |  |  |     bucket_name = "encoding-bucket" | 
					
						
							|  |  |  |     client = boto3.client("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							|  |  |  |     client.create_bucket(Bucket=bucket_name) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     client.put_object(Bucket=bucket_name, Key="foo%2Fbar/data", Body=b"") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     data = client.list_objects_v2(Bucket=bucket_name, Prefix="foo%2Fbar") | 
					
						
							|  |  |  |     assert data["Contents"][0]["Key"].startswith(data["Prefix"]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     data = client.list_objects_v2(Bucket=bucket_name, Prefix="foo%2Fbar", Delimiter="/") | 
					
						
							|  |  |  |     assert data["CommonPrefixes"] == [{"Prefix": "foo%2Fbar/"}] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     client.put_object(Bucket=bucket_name, Key="foo/bar/data", Body=b"") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     data = client.list_objects_v2(Bucket=bucket_name, Delimiter="/") | 
					
						
							|  |  |  |     folders = list( | 
					
						
							|  |  |  |         map(lambda common_prefix: common_prefix["Prefix"], data["CommonPrefixes"]) | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     assert ["foo%2Fbar/", "foo/"] == folders | 
					
						
							| 
									
										
										
										
											2022-08-23 14:48:19 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_s3 | 
					
						
							|  |  |  | @pytest.mark.parametrize("algorithm", ["CRC32", "CRC32C", "SHA1", "SHA256"]) | 
					
						
							|  |  |  | def test_checksum_response(algorithm): | 
					
						
							|  |  |  |     bucket_name = "checksum-bucket" | 
					
						
							|  |  |  |     client = boto3.client("s3", region_name=DEFAULT_REGION_NAME) | 
					
						
							|  |  |  |     client.create_bucket(Bucket=bucket_name) | 
					
						
							|  |  |  |     if ( | 
					
						
							|  |  |  |         algorithm != "CRC32C" | 
					
						
							|  |  |  |     ):  # awscrt is required to allow botocore checksum with CRC32C | 
					
						
							|  |  |  |         response = client.put_object( | 
					
						
							|  |  |  |             Bucket=bucket_name, | 
					
						
							|  |  |  |             Key="test-key", | 
					
						
							|  |  |  |             Body=b"data", | 
					
						
							|  |  |  |             ChecksumAlgorithm=algorithm, | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         assert f"Checksum{algorithm}" in response |