116 lines
4.0 KiB
Python
116 lines
4.0 KiB
Python
from uuid import uuid4
|
|
|
|
import boto3
|
|
import pytest
|
|
|
|
from moto import mock_s3
|
|
|
|
|
|
@mock_s3
|
|
class TestS3ObjectAttributes:
|
|
def setup_method(self, *args) -> None: # pylint: disable=unused-argument
|
|
self.bucket_name = str(uuid4())
|
|
self.s3_resource = boto3.resource("s3", region_name="us-east-1")
|
|
self.client = boto3.client("s3", region_name="us-east-1")
|
|
self.bucket = self.s3_resource.Bucket(self.bucket_name)
|
|
self.bucket.create()
|
|
|
|
self.key = self.bucket.put_object(Key="mykey", Body=b"somedata")
|
|
|
|
def test_get_etag(self):
|
|
actual_etag = self.key.e_tag[1:-1] # etag comes with quotes originally
|
|
resp = self.client.get_object_attributes(
|
|
Bucket=self.bucket_name, Key="mykey", ObjectAttributes=["ETag"]
|
|
)
|
|
|
|
headers = set(resp["ResponseMetadata"]["HTTPHeaders"].keys())
|
|
assert "x-amz-version-id" not in headers
|
|
assert "last-modified" in headers
|
|
|
|
resp.pop("ResponseMetadata")
|
|
|
|
assert set(resp.keys()) == {"ETag", "LastModified"}
|
|
assert resp["ETag"] == actual_etag
|
|
|
|
def test_get_attributes_storageclass(self):
|
|
resp = self.client.get_object_attributes(
|
|
Bucket=self.bucket_name, Key="mykey", ObjectAttributes=["StorageClass"]
|
|
)
|
|
|
|
resp.pop("ResponseMetadata")
|
|
assert set(resp.keys()) == {"StorageClass", "LastModified"}
|
|
assert resp["StorageClass"] == "STANDARD"
|
|
|
|
def test_get_attributes_size(self):
|
|
resp = self.client.get_object_attributes(
|
|
Bucket=self.bucket_name, Key="mykey", ObjectAttributes=["ObjectSize"]
|
|
)
|
|
|
|
resp.pop("ResponseMetadata")
|
|
assert set(resp.keys()) == {"ObjectSize", "LastModified"}
|
|
assert resp["ObjectSize"] == 8
|
|
|
|
@pytest.mark.parametrize(
|
|
"algo_val",
|
|
[
|
|
("CRC32", "6Le+Qw=="),
|
|
("SHA1", "hvfkN/qlp/zhXR3cuerq6jd2Z7g="),
|
|
("SHA256", "ypeBEsobvcr6wjGzmiPcTaeG7/gUfE5yuYB3ha/uSLs="),
|
|
],
|
|
)
|
|
def test_get_attributes_checksum(self, algo_val):
|
|
algo, value = algo_val
|
|
self.client.put_object(
|
|
Bucket=self.bucket_name, Key="cs", Body="a", ChecksumAlgorithm=algo
|
|
)
|
|
|
|
resp = self.client.get_object_attributes(
|
|
Bucket=self.bucket_name, Key="mykey", ObjectAttributes=["Checksum"]
|
|
)
|
|
resp.pop("ResponseMetadata")
|
|
|
|
# Checksum is not returned, because it's not set
|
|
assert set(resp.keys()) == {"LastModified"}
|
|
|
|
# Retrieve checksum from key that was created with CRC32
|
|
resp = self.client.get_object_attributes(
|
|
Bucket=self.bucket_name, Key="cs", ObjectAttributes=["Checksum"]
|
|
)
|
|
|
|
resp.pop("ResponseMetadata")
|
|
assert set(resp.keys()) == {"Checksum", "LastModified"}
|
|
assert resp["Checksum"] == {f"Checksum{algo}": value}
|
|
|
|
def test_get_attributes_multiple(self):
|
|
resp = self.client.get_object_attributes(
|
|
Bucket=self.bucket_name,
|
|
Key="mykey",
|
|
ObjectAttributes=["ObjectSize", "StorageClass"],
|
|
)
|
|
|
|
headers = set(resp["ResponseMetadata"]["HTTPHeaders"].keys())
|
|
assert "x-amz-version-id" not in headers
|
|
|
|
resp.pop("ResponseMetadata")
|
|
assert set(resp.keys()) == {"ObjectSize", "LastModified", "StorageClass"}
|
|
assert resp["ObjectSize"] == 8
|
|
assert resp["StorageClass"] == "STANDARD"
|
|
|
|
def test_get_versioned_object(self):
|
|
self.bucket.Versioning().enable()
|
|
key2 = self.bucket.put_object(Key="mykey", Body=b"moredata")
|
|
|
|
resp = self.client.get_object_attributes(
|
|
Bucket=self.bucket_name, Key="mykey", ObjectAttributes=["ETag"]
|
|
)
|
|
|
|
headers = resp["ResponseMetadata"]["HTTPHeaders"]
|
|
header_keys = set(headers.keys())
|
|
assert "x-amz-version-id" in header_keys
|
|
assert headers["x-amz-version-id"] == key2.version_id
|
|
|
|
resp.pop("ResponseMetadata")
|
|
|
|
assert set(resp.keys()) == {"ETag", "LastModified", "VersionId"}
|
|
assert resp["VersionId"] == key2.version_id
|