Admin: Rework skipped tests for ServerMode (#6833)

This commit is contained in:
Bert Blommers 2023-09-19 19:46:20 +00:00 committed by GitHub
parent 2ada07ff44
commit 643759bd64
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 43 additions and 41 deletions

View File

@ -7,6 +7,8 @@ from typing import List, Optional
TEST_SERVER_MODE = os.environ.get("TEST_SERVER_MODE", "0").lower() == "true" TEST_SERVER_MODE = os.environ.get("TEST_SERVER_MODE", "0").lower() == "true"
TEST_DECORATOR_MODE = not TEST_SERVER_MODE
INITIAL_NO_AUTH_ACTION_COUNT = float( INITIAL_NO_AUTH_ACTION_COUNT = float(
os.environ.get("INITIAL_NO_AUTH_ACTION_COUNT", float("inf")) os.environ.get("INITIAL_NO_AUTH_ACTION_COUNT", float("inf"))
) )

View File

@ -851,7 +851,7 @@ def test_update_authorizer_configuration():
{"op": "add", "path": "/notasetting", "value": "eu-west-1"} {"op": "add", "path": "/notasetting", "value": "eu-west-1"}
], ],
) )
if not settings.TEST_SERVER_MODE: if settings.TEST_DECORATOR_MODE:
assert 'Patch operation "add" not implemented' in str(exc.value) assert 'Patch operation "add" not implemented' in str(exc.value)

View File

@ -10,7 +10,7 @@ from unittest import SkipTest
@mock_apigateway @mock_apigateway
def test_http_integration(): def test_http_integration():
if settings.TEST_SERVER_MODE: if not settings.TEST_DECORATOR_MODE:
raise SkipTest("Cannot test mock of execute-api.apigateway in ServerMode") raise SkipTest("Cannot test mock of execute-api.apigateway in ServerMode")
responses_mock.add( responses_mock.add(
responses_mock.GET, "http://httpbin.org/robots.txt", body="a fake response" responses_mock.GET, "http://httpbin.org/robots.txt", body="a fake response"
@ -58,7 +58,7 @@ def test_http_integration():
@mock_apigateway @mock_apigateway
@mock_dynamodb @mock_dynamodb
def test_aws_integration_dynamodb(): def test_aws_integration_dynamodb():
if settings.TEST_SERVER_MODE: if not settings.TEST_DECORATOR_MODE:
raise SkipTest("Cannot test mock of execute-api.apigateway in ServerMode") raise SkipTest("Cannot test mock of execute-api.apigateway in ServerMode")
client = boto3.client("apigateway", region_name="us-west-2") client = boto3.client("apigateway", region_name="us-west-2")
@ -83,7 +83,7 @@ def test_aws_integration_dynamodb():
@mock_apigateway @mock_apigateway
@mock_dynamodb @mock_dynamodb
def test_aws_integration_dynamodb_multiple_stages(): def test_aws_integration_dynamodb_multiple_stages():
if settings.TEST_SERVER_MODE: if not settings.TEST_DECORATOR_MODE:
raise SkipTest("Cannot test mock of execute-api.apigateway in ServerMode") raise SkipTest("Cannot test mock of execute-api.apigateway in ServerMode")
client = boto3.client("apigateway", region_name="us-west-2") client = boto3.client("apigateway", region_name="us-west-2")
@ -120,7 +120,7 @@ def test_aws_integration_dynamodb_multiple_stages():
@mock_apigateway @mock_apigateway
@mock_dynamodb @mock_dynamodb
def test_aws_integration_dynamodb_multiple_resources(): def test_aws_integration_dynamodb_multiple_resources():
if settings.TEST_SERVER_MODE: if not settings.TEST_DECORATOR_MODE:
raise SkipTest("Cannot test mock of execute-api.apigateway in ServerMode") raise SkipTest("Cannot test mock of execute-api.apigateway in ServerMode")
client = boto3.client("apigateway", region_name="us-west-2") client = boto3.client("apigateway", region_name="us-west-2")

View File

@ -421,7 +421,7 @@ def test_create_function_from_stubbed_ecr():
def test_create_function_from_mocked_ecr_image_tag( def test_create_function_from_mocked_ecr_image_tag(
with_ecr_mock, with_ecr_mock,
): # pylint: disable=unused-argument ): # pylint: disable=unused-argument
if settings.TEST_SERVER_MODE: if not settings.TEST_DECORATOR_MODE:
raise SkipTest( raise SkipTest(
"Envars not easily set in server mode, feature off by default, skipping..." "Envars not easily set in server mode, feature off by default, skipping..."
) )
@ -463,7 +463,7 @@ def test_create_function_from_mocked_ecr_image_tag(
def test_create_function_from_mocked_ecr_image_digest( def test_create_function_from_mocked_ecr_image_digest(
with_ecr_mock, with_ecr_mock,
): # pylint: disable=unused-argument ): # pylint: disable=unused-argument
if settings.TEST_SERVER_MODE: if not settings.TEST_DECORATOR_MODE:
raise SkipTest( raise SkipTest(
"Envars not easily set in server mode, feature off by default, skipping..." "Envars not easily set in server mode, feature off by default, skipping..."
) )
@ -490,7 +490,7 @@ def test_create_function_from_mocked_ecr_image_digest(
def test_create_function_from_mocked_ecr_missing_image( def test_create_function_from_mocked_ecr_missing_image(
with_ecr_mock, with_ecr_mock,
): # pylint: disable=unused-argument ): # pylint: disable=unused-argument
if settings.TEST_SERVER_MODE: if not settings.TEST_DECORATOR_MODE:
raise SkipTest( raise SkipTest(
"Envars not easily set in server mode, feature off by default, skipping..." "Envars not easily set in server mode, feature off by default, skipping..."
) )
@ -1643,7 +1643,7 @@ def test_get_role_name_utility_race_condition():
@mock_lambda @mock_lambda
@mock.patch.dict(os.environ, {"MOTO_LAMBDA_CONCURRENCY_QUOTA": "1000"}) @mock.patch.dict(os.environ, {"MOTO_LAMBDA_CONCURRENCY_QUOTA": "1000"})
def test_put_function_concurrency_success(): def test_put_function_concurrency_success():
if settings.TEST_SERVER_MODE: if not settings.TEST_DECORATOR_MODE:
raise SkipTest( raise SkipTest(
"Envars not easily set in server mode, feature off by default, skipping..." "Envars not easily set in server mode, feature off by default, skipping..."
) )
@ -1697,7 +1697,7 @@ def test_put_function_concurrency_not_enforced():
@mock_lambda @mock_lambda
@mock.patch.dict(os.environ, {"MOTO_LAMBDA_CONCURRENCY_QUOTA": "1000"}) @mock.patch.dict(os.environ, {"MOTO_LAMBDA_CONCURRENCY_QUOTA": "1000"})
def test_put_function_concurrency_failure(): def test_put_function_concurrency_failure():
if settings.TEST_SERVER_MODE: if not settings.TEST_DECORATOR_MODE:
raise SkipTest( raise SkipTest(
"Envars not easily set in server mode, feature off by default, skipping..." "Envars not easily set in server mode, feature off by default, skipping..."
) )
@ -1731,7 +1731,7 @@ def test_put_function_concurrency_failure():
@mock_lambda @mock_lambda
@mock.patch.dict(os.environ, {"MOTO_LAMBDA_CONCURRENCY_QUOTA": "1000"}) @mock.patch.dict(os.environ, {"MOTO_LAMBDA_CONCURRENCY_QUOTA": "1000"})
def test_put_function_concurrency_i_can_has_math(): def test_put_function_concurrency_i_can_has_math():
if settings.TEST_SERVER_MODE: if not settings.TEST_DECORATOR_MODE:
raise SkipTest( raise SkipTest(
"Envars not easily set in server mode, feature off by default, skipping..." "Envars not easily set in server mode, feature off by default, skipping..."
) )

View File

@ -12,7 +12,7 @@ BASE_URL = f"http://localhost:{SERVER_PORT}/"
class TestAccountIdResolution: class TestAccountIdResolution:
def setup_method(self): def setup_method(self):
if settings.TEST_SERVER_MODE: if not settings.TEST_DECORATOR_MODE:
raise SkipTest( raise SkipTest(
"No point in testing this in ServerMode, as we already start our own server" "No point in testing this in ServerMode, as we already start our own server"
) )

View File

@ -110,7 +110,7 @@ def test_key_save_to_missing_bucket():
@mock_s3 @mock_s3
def test_missing_key_request(): def test_missing_key_request():
if settings.TEST_SERVER_MODE: if not settings.TEST_DECORATOR_MODE:
raise SkipTest("Only test status code in non-ServerMode") raise SkipTest("Only test status code in non-ServerMode")
s3_client = boto3.client("s3", region_name=DEFAULT_REGION_NAME) s3_client = boto3.client("s3", region_name=DEFAULT_REGION_NAME)
s3_client.create_bucket(Bucket="foobar") s3_client.create_bucket(Bucket="foobar")
@ -223,7 +223,7 @@ def test_last_modified():
assert isinstance(resp["LastModified"], datetime.datetime) assert isinstance(resp["LastModified"], datetime.datetime)
as_header = resp["ResponseMetadata"]["HTTPHeaders"]["last-modified"] as_header = resp["ResponseMetadata"]["HTTPHeaders"]["last-modified"]
assert isinstance(as_header, str) assert isinstance(as_header, str)
if not settings.TEST_SERVER_MODE: if settings.TEST_DECORATOR_MODE:
assert as_header == "Sun, 01 Jan 2012 12:00:00 GMT" assert as_header == "Sun, 01 Jan 2012 12:00:00 GMT"
@ -313,7 +313,7 @@ def test_get_all_buckets():
@mock_s3 @mock_s3
def test_post_to_bucket(): def test_post_to_bucket():
if settings.TEST_SERVER_MODE: if not settings.TEST_DECORATOR_MODE:
# ServerMode does not allow unauthorized requests # ServerMode does not allow unauthorized requests
raise SkipTest() raise SkipTest()
@ -330,7 +330,7 @@ def test_post_to_bucket():
@mock_s3 @mock_s3
def test_post_with_metadata_to_bucket(): def test_post_with_metadata_to_bucket():
if settings.TEST_SERVER_MODE: if not settings.TEST_DECORATOR_MODE:
# ServerMode does not allow unauthorized requests # ServerMode does not allow unauthorized requests
raise SkipTest() raise SkipTest()
client = boto3.client("s3", region_name=DEFAULT_REGION_NAME) client = boto3.client("s3", region_name=DEFAULT_REGION_NAME)
@ -540,7 +540,7 @@ def test_restore_key():
key.restore_object(RestoreRequest={"Days": 1}) key.restore_object(RestoreRequest={"Days": 1})
if settings.TEST_SERVER_MODE: if settings.TEST_SERVER_MODE:
assert 'ongoing-request="false"' in key.restore assert 'ongoing-request="false"' in key.restore
else: elif settings.TEST_DECORATOR_MODE:
assert key.restore == ( assert key.restore == (
'ongoing-request="false", expiry-date="Mon, 02 Jan 2012 12:00:00 GMT"' 'ongoing-request="false", expiry-date="Mon, 02 Jan 2012 12:00:00 GMT"'
) )
@ -549,7 +549,7 @@ def test_restore_key():
if settings.TEST_SERVER_MODE: if settings.TEST_SERVER_MODE:
assert 'ongoing-request="false"' in key.restore assert 'ongoing-request="false"' in key.restore
else: elif settings.TEST_DECORATOR_MODE:
assert key.restore == ( assert key.restore == (
'ongoing-request="false", expiry-date="Tue, 03 Jan 2012 12:00:00 GMT"' 'ongoing-request="false", expiry-date="Tue, 03 Jan 2012 12:00:00 GMT"'
) )
@ -558,7 +558,7 @@ def test_restore_key():
@freeze_time("2012-01-01 12:00:00") @freeze_time("2012-01-01 12:00:00")
@mock_s3 @mock_s3
def test_restore_key_transition(): def test_restore_key_transition():
if settings.TEST_SERVER_MODE: if not settings.TEST_DECORATOR_MODE:
raise SkipTest("Can't set transition directly in ServerMode") raise SkipTest("Can't set transition directly in ServerMode")
state_manager.set_transition( state_manager.set_transition(
@ -2828,7 +2828,7 @@ def test_paths_with_leading_slashes_work():
@mock_s3 @mock_s3
def test_root_dir_with_empty_name_works(): def test_root_dir_with_empty_name_works():
if settings.TEST_SERVER_MODE: if not settings.TEST_DECORATOR_MODE:
raise SkipTest("Does not work in server mode due to error in Workzeug") raise SkipTest("Does not work in server mode due to error in Workzeug")
store_and_read_back_a_key("/") store_and_read_back_a_key("/")

View File

@ -12,7 +12,7 @@ from moto.core import DEFAULT_ACCOUNT_ID as ACCOUNT_ID, set_initial_no_auth_acti
@mock_s3 @mock_s3
@set_initial_no_auth_action_count(0) @set_initial_no_auth_action_count(0)
def test_load_unexisting_object_without_auth_should_return_403(): def test_load_unexisting_object_without_auth_should_return_403():
if settings.TEST_SERVER_MODE: if not settings.TEST_DECORATOR_MODE:
raise SkipTest("Auth decorator does not work in server mode") raise SkipTest("Auth decorator does not work in server mode")
# Head an S3 object we should have no access to. # Head an S3 object we should have no access to.
@ -31,7 +31,7 @@ def test_load_unexisting_object_without_auth_should_return_403():
@set_initial_no_auth_action_count(4) @set_initial_no_auth_action_count(4)
@mock_s3 @mock_s3
def test_head_bucket_with_correct_credentials(): def test_head_bucket_with_correct_credentials():
if settings.TEST_SERVER_MODE: if not settings.TEST_DECORATOR_MODE:
raise SkipTest("Auth decorator does not work in server mode") raise SkipTest("Auth decorator does not work in server mode")
# These calls are all unauthenticated # These calls are all unauthenticated
@ -62,7 +62,7 @@ def test_head_bucket_with_correct_credentials():
@set_initial_no_auth_action_count(4) @set_initial_no_auth_action_count(4)
@mock_s3 @mock_s3
def test_head_bucket_with_incorrect_credentials(): def test_head_bucket_with_incorrect_credentials():
if settings.TEST_SERVER_MODE: if not settings.TEST_DECORATOR_MODE:
raise SkipTest("Auth decorator does not work in server mode") raise SkipTest("Auth decorator does not work in server mode")
# These calls are all authenticated # These calls are all authenticated
@ -152,7 +152,7 @@ def create_role_with_attached_policy_and_assume_it(
@mock_s3 @mock_s3
@mock_sts @mock_sts
def test_delete_objects_without_access_throws_custom_error(): def test_delete_objects_without_access_throws_custom_error():
if settings.TEST_SERVER_MODE: if not settings.TEST_DECORATOR_MODE:
raise SkipTest("Auth decorator does not work in server mode") raise SkipTest("Auth decorator does not work in server mode")
role_name = "some-test-role" role_name = "some-test-role"

View File

@ -11,7 +11,7 @@ from moto.s3.responses import DEFAULT_REGION_NAME
@mock_s3 @mock_s3
def test_cross_account_region_access(): def test_cross_account_region_access():
if settings.TEST_SERVER_MODE: if not settings.TEST_DECORATOR_MODE:
raise SkipTest("Multi-accounts env config only works serverside") raise SkipTest("Multi-accounts env config only works serverside")
client1 = boto3.client("s3", region_name=DEFAULT_REGION_NAME) client1 = boto3.client("s3", region_name=DEFAULT_REGION_NAME)

View File

@ -15,7 +15,7 @@ CUSTOM_ENDPOINT_2 = "https://caf-o.s3-ext.jc.rl.ac.uk"
@pytest.mark.parametrize("url", [CUSTOM_ENDPOINT, CUSTOM_ENDPOINT_2]) @pytest.mark.parametrize("url", [CUSTOM_ENDPOINT, CUSTOM_ENDPOINT_2])
def test_create_and_list_buckets(url): def test_create_and_list_buckets(url):
if settings.TEST_SERVER_MODE: if not settings.TEST_DECORATOR_MODE:
raise SkipTest("Unable to set ENV VAR in ServerMode") raise SkipTest("Unable to set ENV VAR in ServerMode")
# Have to inline this, as the URL-param is not available as a context decorator # Have to inline this, as the URL-param is not available as a context decorator
with patch.dict(os.environ, {"MOTO_S3_CUSTOM_ENDPOINTS": url}): with patch.dict(os.environ, {"MOTO_S3_CUSTOM_ENDPOINTS": url}):
@ -32,7 +32,7 @@ def test_create_and_list_buckets(url):
@pytest.mark.parametrize("url", [CUSTOM_ENDPOINT, CUSTOM_ENDPOINT_2]) @pytest.mark.parametrize("url", [CUSTOM_ENDPOINT, CUSTOM_ENDPOINT_2])
def test_create_and_list_buckets_with_multiple_supported_endpoints(url): def test_create_and_list_buckets_with_multiple_supported_endpoints(url):
if settings.TEST_SERVER_MODE: if not settings.TEST_DECORATOR_MODE:
raise SkipTest("Unable to set ENV VAR in ServerMode") raise SkipTest("Unable to set ENV VAR in ServerMode")
# Have to inline this, as the URL-param is not available as a context decorator # Have to inline this, as the URL-param is not available as a context decorator
with patch.dict( with patch.dict(
@ -53,7 +53,7 @@ def test_create_and_list_buckets_with_multiple_supported_endpoints(url):
@pytest.mark.parametrize("url", [CUSTOM_ENDPOINT, CUSTOM_ENDPOINT_2]) @pytest.mark.parametrize("url", [CUSTOM_ENDPOINT, CUSTOM_ENDPOINT_2])
@mock_s3 @mock_s3
def test_put_and_get_object(url): def test_put_and_get_object(url):
if settings.TEST_SERVER_MODE: if not settings.TEST_DECORATOR_MODE:
raise SkipTest("Unable to set ENV VAR in ServerMode") raise SkipTest("Unable to set ENV VAR in ServerMode")
with patch.dict(os.environ, {"MOTO_S3_CUSTOM_ENDPOINTS": url}): with patch.dict(os.environ, {"MOTO_S3_CUSTOM_ENDPOINTS": url}):
with mock_s3(): with mock_s3():
@ -74,7 +74,7 @@ def test_put_and_get_object(url):
@pytest.mark.parametrize("url", [CUSTOM_ENDPOINT, CUSTOM_ENDPOINT_2]) @pytest.mark.parametrize("url", [CUSTOM_ENDPOINT, CUSTOM_ENDPOINT_2])
@mock_s3 @mock_s3
def test_put_and_list_objects(url): def test_put_and_list_objects(url):
if settings.TEST_SERVER_MODE: if not settings.TEST_DECORATOR_MODE:
raise SkipTest("Unable to set ENV VAR in ServerMode") raise SkipTest("Unable to set ENV VAR in ServerMode")
with patch.dict(os.environ, {"MOTO_S3_CUSTOM_ENDPOINTS": url}): with patch.dict(os.environ, {"MOTO_S3_CUSTOM_ENDPOINTS": url}):
with mock_s3(): with mock_s3():

View File

@ -48,7 +48,7 @@ class TestS3FileHandleClosures(TestCase):
""" """
def setUp(self) -> None: def setUp(self) -> None:
if settings.TEST_SERVER_MODE: if not settings.TEST_DECORATOR_MODE:
raise SkipTest("No point in testing ServerMode, we're not using boto3") raise SkipTest("No point in testing ServerMode, we're not using boto3")
self.s3_client = s3_backends[DEFAULT_ACCOUNT_ID]["global"] self.s3_client = s3_backends[DEFAULT_ACCOUNT_ID]["global"]
self.s3_client.create_bucket(TEST_BUCKET, "us-west-1") self.s3_client.create_bucket(TEST_BUCKET, "us-west-1")

View File

@ -274,7 +274,7 @@ def test_log_file_is_created():
@mock_s3 @mock_s3
def test_invalid_bucket_logging_when_permissions_are_false(): def test_invalid_bucket_logging_when_permissions_are_false():
if settings.TEST_SERVER_MODE: if not settings.TEST_DECORATOR_MODE:
raise SkipTest("Can't patch permission logic in ServerMode") raise SkipTest("Can't patch permission logic in ServerMode")
s3_client = boto3.client("s3", region_name=DEFAULT_REGION_NAME) s3_client = boto3.client("s3", region_name=DEFAULT_REGION_NAME)
@ -300,7 +300,7 @@ def test_invalid_bucket_logging_when_permissions_are_false():
@mock_s3 @mock_s3
def test_valid_bucket_logging_when_permissions_are_true(): def test_valid_bucket_logging_when_permissions_are_true():
if settings.TEST_SERVER_MODE: if not settings.TEST_DECORATOR_MODE:
raise SkipTest("Can't patch permission logic in ServerMode") raise SkipTest("Can't patch permission logic in ServerMode")
s3_client = boto3.client("s3", region_name=DEFAULT_REGION_NAME) s3_client = boto3.client("s3", region_name=DEFAULT_REGION_NAME)
@ -329,7 +329,7 @@ def test_valid_bucket_logging_when_permissions_are_true():
@mock_s3 @mock_s3
def test_bucket_policy_not_set(): def test_bucket_policy_not_set():
if settings.TEST_SERVER_MODE: if not settings.TEST_DECORATOR_MODE:
raise SkipTest("Can't patch permission logic in ServerMode") raise SkipTest("Can't patch permission logic in ServerMode")
s3_client = boto3.client("s3", region_name=DEFAULT_REGION_NAME) s3_client = boto3.client("s3", region_name=DEFAULT_REGION_NAME)
@ -349,7 +349,7 @@ def test_bucket_policy_not_set():
@mock_s3 @mock_s3
def test_bucket_policy_principal(): def test_bucket_policy_principal():
if settings.TEST_SERVER_MODE: if not settings.TEST_DECORATOR_MODE:
raise SkipTest("Can't patch permission logic in ServerMode") raise SkipTest("Can't patch permission logic in ServerMode")
s3_client = boto3.client("s3", region_name=DEFAULT_REGION_NAME) s3_client = boto3.client("s3", region_name=DEFAULT_REGION_NAME)
@ -404,7 +404,7 @@ def test_bucket_policy_principal():
@mock_s3 @mock_s3
def test_bucket_policy_effect(): def test_bucket_policy_effect():
if settings.TEST_SERVER_MODE: if not settings.TEST_DECORATOR_MODE:
raise SkipTest("Can't patch permission logic in ServerMode") raise SkipTest("Can't patch permission logic in ServerMode")
s3_client = boto3.client("s3", region_name=DEFAULT_REGION_NAME) s3_client = boto3.client("s3", region_name=DEFAULT_REGION_NAME)
@ -458,7 +458,7 @@ def test_bucket_policy_effect():
@mock_s3 @mock_s3
def test_bucket_policy_action(): def test_bucket_policy_action():
if settings.TEST_SERVER_MODE: if not settings.TEST_DECORATOR_MODE:
raise SkipTest("Can't patch permission logic in ServerMode") raise SkipTest("Can't patch permission logic in ServerMode")
s3_client = boto3.client("s3", region_name=DEFAULT_REGION_NAME) s3_client = boto3.client("s3", region_name=DEFAULT_REGION_NAME)
@ -510,7 +510,7 @@ def test_bucket_policy_action():
@mock_s3 @mock_s3
def test_bucket_policy_resource(): def test_bucket_policy_resource():
if settings.TEST_SERVER_MODE: if not settings.TEST_DECORATOR_MODE:
raise SkipTest("Can't patch permission logic in ServerMode") raise SkipTest("Can't patch permission logic in ServerMode")
s3_client = boto3.client("s3", region_name=DEFAULT_REGION_NAME) s3_client = boto3.client("s3", region_name=DEFAULT_REGION_NAME)

View File

@ -13,12 +13,12 @@ import moto.s3.models as s3model
from moto.s3.responses import DEFAULT_REGION_NAME from moto.s3.responses import DEFAULT_REGION_NAME
from moto.settings import get_s3_default_key_buffer_size, S3_UPLOAD_PART_MIN_SIZE from moto.settings import get_s3_default_key_buffer_size, S3_UPLOAD_PART_MIN_SIZE
if settings.TEST_SERVER_MODE: if settings.TEST_DECORATOR_MODE:
REDUCED_PART_SIZE = S3_UPLOAD_PART_MIN_SIZE
EXPECTED_ETAG = '"140f92a6df9f9e415f74a1463bcee9bb-2"'
else:
REDUCED_PART_SIZE = 256 REDUCED_PART_SIZE = 256
EXPECTED_ETAG = '"66d1a1a2ed08fd05c137f316af4ff255-2"' EXPECTED_ETAG = '"66d1a1a2ed08fd05c137f316af4ff255-2"'
else:
REDUCED_PART_SIZE = S3_UPLOAD_PART_MIN_SIZE
EXPECTED_ETAG = '"140f92a6df9f9e415f74a1463bcee9bb-2"'
def reduced_min_part_size(func): def reduced_min_part_size(func):