|
| 1 | +from typing import Any |
| 2 | + |
| 3 | +from mypy_boto3_s3.client import S3Client |
| 4 | + |
| 5 | +from s3mock_test import given_bucket, UPLOAD_FILE_NAME, compute_md5_etag, compute_sha256_checksum_b64 |
| 6 | + |
| 7 | + |
| 8 | +# reimplementation of https://github.com/adobe/S3Mock/blob/main/integration-tests/src/test/kotlin/com/adobe/testing/s3mock/its/AwsChunkedEncodingIT.kt |
| 9 | + |
| 10 | +def test_put_object_with_checksum_returns_correct_checksum_get_object_returns_checksum(s3_client_http: S3Client, bucket_name: str) -> None: |
| 11 | + # Arrange |
| 12 | + given_bucket(s3_client_http, bucket_name) |
| 13 | + |
| 14 | + with open(UPLOAD_FILE_NAME, "rb") as f: |
| 15 | + payload = f.read() |
| 16 | + |
| 17 | + expected_etag = compute_md5_etag(payload) |
| 18 | + expected_checksum = compute_sha256_checksum_b64(payload) |
| 19 | + expected_length = len(payload) |
| 20 | + |
| 21 | + # Act - PutObject with checksum |
| 22 | + put_resp: dict[str, Any] = s3_client_http.put_object( |
| 23 | + Bucket=bucket_name, |
| 24 | + Key=UPLOAD_FILE_NAME, |
| 25 | + Body=payload, |
| 26 | + ChecksumAlgorithm="SHA256", |
| 27 | + ) |
| 28 | + |
| 29 | + # Assert - PutObject response checksum |
| 30 | + put_checksum = put_resp.get("ChecksumSHA256") |
| 31 | + assert put_checksum, "ChecksumSHA256 should be present on PutObject response" |
| 32 | + assert put_checksum == expected_checksum, "ChecksumSHA256 should match expected SHA256 (base64)" |
| 33 | + |
| 34 | + # Act - GetObject with checksum mode enabled |
| 35 | + get_resp: dict[str, Any] = s3_client_http.get_object( |
| 36 | + Bucket=bucket_name, |
| 37 | + Key=UPLOAD_FILE_NAME, |
| 38 | + ChecksumMode='ENABLED', |
| 39 | + ) |
| 40 | + |
| 41 | + assert get_resp.get("ETag") == expected_etag |
| 42 | + assert get_resp.get("ContentLength") == expected_length |
| 43 | + assert get_resp.get("ChecksumSHA256") == expected_checksum |
| 44 | + assert get_resp.get("ContentEncoding") != 'aws-chunked' |
| 45 | + |
| 46 | +def test_put_object_creates_correct_etag_get_object_returns_etag(s3_client_http: S3Client, bucket_name: str) -> None: |
| 47 | + # Arrange |
| 48 | + given_bucket(s3_client_http, bucket_name) |
| 49 | + |
| 50 | + with open(UPLOAD_FILE_NAME, "rb") as f: |
| 51 | + payload = f.read() |
| 52 | + |
| 53 | + expected_etag = compute_md5_etag(payload) |
| 54 | + expected_length = len(payload) |
| 55 | + |
| 56 | + # Act - PutObject (no checksum, single part) |
| 57 | + s3_client_http.put_object( |
| 58 | + Bucket=bucket_name, |
| 59 | + Key=UPLOAD_FILE_NAME, |
| 60 | + Body=payload, |
| 61 | + ) |
| 62 | + |
| 63 | + # Act - GetObject |
| 64 | + get_resp: dict[str, Any] = s3_client_http.get_object( |
| 65 | + Bucket=bucket_name, |
| 66 | + Key=UPLOAD_FILE_NAME, |
| 67 | + ) |
| 68 | + |
| 69 | + # Assert |
| 70 | + assert get_resp.get("ETag") == expected_etag |
| 71 | + assert get_resp.get("ContentLength") == expected_length |
| 72 | + assert get_resp.get("ContentEncoding") != "aws-chunked" |
| 73 | + |
| 74 | +def test_put_object_sets_content_encoding_get_object_returns_content_encoding(s3_client_http: S3Client, bucket_name: str) -> None: |
| 75 | + # Arrange |
| 76 | + given_bucket(s3_client_http, bucket_name) |
| 77 | + custom_encoding = "my-custom-encoding" |
| 78 | + |
| 79 | + with open(UPLOAD_FILE_NAME, "rb") as f: |
| 80 | + payload = f.read() |
| 81 | + |
| 82 | + # Act - PutObject with custom Content-Encoding |
| 83 | + s3_client_http.put_object( |
| 84 | + Bucket=bucket_name, |
| 85 | + Key=UPLOAD_FILE_NAME, |
| 86 | + Body=payload, |
| 87 | + ContentEncoding=custom_encoding, |
| 88 | + ) |
| 89 | + |
| 90 | + # Act - GetObject |
| 91 | + get_resp: dict[str, Any] = s3_client_http.get_object( |
| 92 | + Bucket=bucket_name, |
| 93 | + Key=UPLOAD_FILE_NAME, |
| 94 | + ) |
| 95 | + |
| 96 | + # Assert - ContentEncoding is preserved |
| 97 | + assert get_resp.get("ContentEncoding") == custom_encoding |
| 98 | + |
0 commit comments