Skip to content

Conversation

@amwolff
Copy link

@amwolff amwolff commented Dec 7, 2025

I've run all auth-related tests against AWS S3 and found that there are some tests failing there. While the problem is likely with all these tests themselves, hence they are marked as failing on the Rados gateway, there are tests failing on the Rados gateway that are not failing on AWS. So, I thought it was worth preserving the ability to use the fails_on_aws marker by marking these as failing on AWS. Here's the full test run:

GLOB sdist-make: /workspaces/s3-tests/setup.py
py inst-nodeps: /workspaces/s3-tests/.tox/.tmp/package/1/s3tests-0.0.1.zip
py installed: boto3==1.42.1,botocore==1.42.1,cachetools==6.2.2,certifi==2025.11.12,chardet==5.2.0,charset-normalizer==3.4.4,colorama==0.4.6,distlib==0.4.0,exceptiongroup==1.3.1,filelock==3.19.1,gevent==25.9.1,greenlet==3.2.4,httplib2==0.31.0,idna==3.11,iniconfig==2.1.0,isodate==0.7.2,jmespath==1.0.1,lxml==6.0.2,munch==4.0.0,packaging==25.0,platformdirs==4.4.0,pluggy==1.6.0,pygments==2.19.2,pyparsing==3.2.5,pyproject-api==1.9.1,pytest==8.4.2,python-dateutil==2.9.0.post0,pytz==2025.2,pyyaml==6.0.3,requests==2.32.5,s3tests @ file:///workspaces/s3-tests/.tox/.tmp/package/1/s3tests-0.0.1.zip,s3transfer==0.16.0,six==1.17.0,tomli==2.3.0,tox==4.30.3,typing-extensions==4.15.0,urllib3==1.26.20,virtualenv==20.35.4,zope-event==6.0,zope-interface==8.0.1
py run-test-pre: PYTHONHASHSEED='2682684239'
py run-test: commands[0] | pytest -m 'auth_aws2 or auth_aws4 or auth_common'
============================= test session starts ==============================
platform linux -- Python 3.9.2, pytest-8.4.2, pluggy-1.6.0
cachedir: .tox/py/.pytest_cache
rootdir: /workspaces/s3-tests
configfile: pytest.ini
collected 1041 items / 993 deselected / 48 selected

s3tests/functional/test_headers.py .......F.F...FFFF.F......FF..FF....F. [ 77%]
..FFF..F...                                                              [100%]

=================================== FAILURES ===================================
__________________ test_object_create_bad_contentlength_empty __________________

    @pytest.mark.auth_common
    # TODO: remove 'fails_on_rgw' and once we have learned how to remove the content-length header
    @pytest.mark.fails_on_rgw
    def test_object_create_bad_contentlength_empty():
>       e = _add_header_create_bad_object({'Content-Length':''})

s3tests/functional/test_headers.py:206: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
s3tests/functional/test_headers.py:47: in _add_header_create_bad_object
    e = assert_raises(ClientError, client.put_object, Bucket=bucket_name, Key=key_name, Body='bar')
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

excClass = <class 'botocore.exceptions.ClientError'>
callableObj = <bound method ClientCreator._create_api_method.<locals>._api_call of <botocore.client.S3 object at 0x7f9defd19be0>>
args = ()
kwargs = {'Body': 'bar', 'Bucket': 'yournamehere-al4ti6vy4wr2ctvr-8', 'Key': 'foo'}
excName = 'ClientError'

    def assert_raises(excClass, callableObj, *args, **kwargs):
        """
        Like unittest.TestCase.assertRaises, but returns the exception.
        """
        try:
            callableObj(*args, **kwargs)
        except excClass as e:
            return e
        else:
            if hasattr(excClass, '__name__'):
                excName = excClass.__name__
            else:
                excName = str(excClass)
>           raise AssertionError("%s not raised" % excName)
E           AssertionError: ClientError not raised

s3tests/functional/utils.py:19: AssertionError
---------------------------- Captured stdout setup -----------------------------
Done with cleanup of buckets in tests.
Done with cleanup of buckets in tests.
Done with cleanup of buckets in tests.
--------------------------- Captured stdout teardown ---------------------------
Done with cleanup of buckets in tests.
Done with cleanup of buckets in tests.
Done with cleanup of buckets in tests.
__________________ test_object_create_bad_contentlength_none ___________________

    @pytest.mark.auth_common
    # TODO: remove 'fails_on_rgw' and once we have learned how to remove the content-length header
    @pytest.mark.fails_on_rgw
    def test_object_create_bad_contentlength_none():
        remove = 'Content-Length'
>       e = _remove_header_create_bad_object('Content-Length')

s3tests/functional/test_headers.py:228: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
s3tests/functional/test_headers.py:84: in _remove_header_create_bad_object
    e = assert_raises(ClientError, client.put_object, Bucket=bucket_name, Key=key_name, Body='bar')
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

excClass = <class 'botocore.exceptions.ClientError'>
callableObj = <bound method ClientCreator._create_api_method.<locals>._api_call of <botocore.client.S3 object at 0x7f9def915340>>
args = ()
kwargs = {'Body': 'bar', 'Bucket': 'yournamehere-al4ti6vy4wr2ctvr-10', 'Key': 'foo'}
excName = 'ClientError'

    def assert_raises(excClass, callableObj, *args, **kwargs):
        """
        Like unittest.TestCase.assertRaises, but returns the exception.
        """
        try:
            callableObj(*args, **kwargs)
        except excClass as e:
            return e
        else:
            if hasattr(excClass, '__name__'):
                excName = excClass.__name__
            else:
                excName = str(excClass)
>           raise AssertionError("%s not raised" % excName)
E           AssertionError: ClientError not raised

s3tests/functional/utils.py:19: AssertionError
---------------------------- Captured stdout setup -----------------------------
Done with cleanup of buckets in tests.
Done with cleanup of buckets in tests.
Done with cleanup of buckets in tests.
--------------------------- Captured stdout teardown ---------------------------
Done with cleanup of buckets in tests.
Done with cleanup of buckets in tests.
Done with cleanup of buckets in tests.
__________________ test_object_create_bad_authorization_empty __________________

    @pytest.mark.auth_common
    # TODO: remove 'fails_on_rgw' and once we have learned how to remove the authorization header
    @pytest.mark.fails_on_rgw
    def test_object_create_bad_authorization_empty():
>       e = _add_header_create_bad_object({'Authorization': ''})

s3tests/functional/test_headers.py:259: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
s3tests/functional/test_headers.py:47: in _add_header_create_bad_object
    e = assert_raises(ClientError, client.put_object, Bucket=bucket_name, Key=key_name, Body='bar')
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

excClass = <class 'botocore.exceptions.ClientError'>
callableObj = <bound method ClientCreator._create_api_method.<locals>._api_call of <botocore.client.S3 object at 0x7f9defef9610>>
args = ()
kwargs = {'Body': 'bar', 'Bucket': 'yournamehere-al4ti6vy4wr2ctvr-14', 'Key': 'foo'}
excName = 'ClientError'

    def assert_raises(excClass, callableObj, *args, **kwargs):
        """
        Like unittest.TestCase.assertRaises, but returns the exception.
        """
        try:
            callableObj(*args, **kwargs)
        except excClass as e:
            return e
        else:
            if hasattr(excClass, '__name__'):
                excName = excClass.__name__
            else:
                excName = str(excClass)
>           raise AssertionError("%s not raised" % excName)
E           AssertionError: ClientError not raised

s3tests/functional/utils.py:19: AssertionError
---------------------------- Captured stdout setup -----------------------------
Done with cleanup of buckets in tests.
Done with cleanup of buckets in tests.
Done with cleanup of buckets in tests.
--------------------------- Captured stdout teardown ---------------------------
Done with cleanup of buckets in tests.
Done with cleanup of buckets in tests.
Done with cleanup of buckets in tests.
_____________________ test_object_create_date_and_amz_date _____________________

    @pytest.mark.auth_common
    # TODO: remove 'fails_on_rgw' and once we have learned how to pass both the 'Date' and 'X-Amz-Date' header during signing and not 'X-Amz-Date' before
    @pytest.mark.fails_on_rgw
    def test_object_create_date_and_amz_date():
        date = formatdate(usegmt=True)
>       bucket_name, key_name = _add_header_create_object({'Date': date, 'X-Amz-Date': date})

s3tests/functional/test_headers.py:268: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
s3tests/functional/test_headers.py:31: in _add_header_create_object
    client.put_object(Bucket=bucket_name, Key=key_name)
.tox/py/lib/python3.9/site-packages/botocore/client.py:602: in _api_call
    return self._make_api_call(operation_name, kwargs)
.tox/py/lib/python3.9/site-packages/botocore/context.py:123: in wrapper
    return func(*args, **kwargs)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <botocore.client.S3 object at 0x7f9def814640>
operation_name = 'PutObject'
api_params = {'Bucket': 'yournamehere-al4ti6vy4wr2ctvr-15', 'Key': 'foo'}

    @with_current_context()
    def _make_api_call(self, operation_name, api_params):
        operation_model = self._service_model.operation_model(operation_name)
        service_name = self._service_model.service_name
        history_recorder.record(
            'API_CALL',
            {
                'service': service_name,
                'operation': operation_name,
                'params': api_params,
            },
        )
        if operation_model.deprecated:
            logger.debug(
                'Warning: %s.%s() is deprecated', service_name, operation_name
            )
        request_context = {
            'client_region': self.meta.region_name,
            'client_config': self.meta.config,
            'has_streaming_input': operation_model.has_streaming_input,
            'auth_type': operation_model.resolved_auth_type,
            'unsigned_payload': operation_model.unsigned_payload,
            'auth_options': self._service_model.metadata.get('auth'),
        }
    
        api_params = self._emit_api_params(
            api_params=api_params,
            operation_model=operation_model,
            context=request_context,
        )
        (
            endpoint_url,
            additional_headers,
            properties,
        ) = self._resolve_endpoint_ruleset(
            operation_model, api_params, request_context
        )
        if properties:
            # Pass arbitrary endpoint info with the Request
            # for use during construction.
            request_context['endpoint_properties'] = properties
        request_dict = self._convert_to_request_dict(
            api_params=api_params,
            operation_model=operation_model,
            endpoint_url=endpoint_url,
            context=request_context,
            headers=additional_headers,
        )
        resolve_checksum_context(request_dict, operation_model, api_params)
    
        service_id = self._service_model.service_id.hyphenize()
        handler, event_response = self.meta.events.emit_until_response(
            f'before-call.{service_id}.{operation_name}',
            model=operation_model,
            params=request_dict,
            request_signer=self._request_signer,
            context=request_context,
        )
    
        if event_response is not None:
            http, parsed_response = event_response
        else:
            maybe_compress_request(
                self.meta.config, request_dict, operation_model
            )
            apply_request_checksum(request_dict)
            http, parsed_response = self._make_request(
                operation_model, request_dict, request_context
            )
    
        self.meta.events.emit(
            f'after-call.{service_id}.{operation_name}',
            http_response=http,
            parsed=parsed_response,
            model=operation_model,
            context=request_context,
        )
    
        if http.status_code >= 300:
            error_info = parsed_response.get("Error", {})
            error_code = request_context.get(
                'error_code_override'
            ) or error_info.get("Code")
            error_class = self.exceptions.from_code(error_code)
>           raise error_class(parsed_response, operation_name)
E           botocore.exceptions.ClientError: An error occurred (SignatureDoesNotMatch) when calling the PutObject operation: The request signature we calculated does not match the signature you provided. Check your key and signing method.

.tox/py/lib/python3.9/site-packages/botocore/client.py:1078: ClientError
---------------------------- Captured stdout setup -----------------------------
Done with cleanup of buckets in tests.
Done with cleanup of buckets in tests.
Done with cleanup of buckets in tests.
--------------------------- Captured stdout teardown ---------------------------
Done with cleanup of buckets in tests.
Done with cleanup of buckets in tests.
Done with cleanup of buckets in tests.
___________________ test_object_create_amz_date_and_no_date ____________________

    @pytest.mark.auth_common
    # TODO: remove 'fails_on_rgw' and once we have learned how to pass both the 'Date' and 'X-Amz-Date' header during signing and not 'X-Amz-Date' before
    @pytest.mark.fails_on_rgw
    def test_object_create_amz_date_and_no_date():
        date = formatdate(usegmt=True)
>       bucket_name, key_name = _add_header_create_object({'Date': '', 'X-Amz-Date': date})

s3tests/functional/test_headers.py:277: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
s3tests/functional/test_headers.py:31: in _add_header_create_object
    client.put_object(Bucket=bucket_name, Key=key_name)
.tox/py/lib/python3.9/site-packages/botocore/client.py:602: in _api_call
    return self._make_api_call(operation_name, kwargs)
.tox/py/lib/python3.9/site-packages/botocore/context.py:123: in wrapper
    return func(*args, **kwargs)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <botocore.client.S3 object at 0x7f9defe01190>
operation_name = 'PutObject'
api_params = {'Bucket': 'yournamehere-al4ti6vy4wr2ctvr-16', 'Key': 'foo'}

    @with_current_context()
    def _make_api_call(self, operation_name, api_params):
        operation_model = self._service_model.operation_model(operation_name)
        service_name = self._service_model.service_name
        history_recorder.record(
            'API_CALL',
            {
                'service': service_name,
                'operation': operation_name,
                'params': api_params,
            },
        )
        if operation_model.deprecated:
            logger.debug(
                'Warning: %s.%s() is deprecated', service_name, operation_name
            )
        request_context = {
            'client_region': self.meta.region_name,
            'client_config': self.meta.config,
            'has_streaming_input': operation_model.has_streaming_input,
            'auth_type': operation_model.resolved_auth_type,
            'unsigned_payload': operation_model.unsigned_payload,
            'auth_options': self._service_model.metadata.get('auth'),
        }
    
        api_params = self._emit_api_params(
            api_params=api_params,
            operation_model=operation_model,
            context=request_context,
        )
        (
            endpoint_url,
            additional_headers,
            properties,
        ) = self._resolve_endpoint_ruleset(
            operation_model, api_params, request_context
        )
        if properties:
            # Pass arbitrary endpoint info with the Request
            # for use during construction.
            request_context['endpoint_properties'] = properties
        request_dict = self._convert_to_request_dict(
            api_params=api_params,
            operation_model=operation_model,
            endpoint_url=endpoint_url,
            context=request_context,
            headers=additional_headers,
        )
        resolve_checksum_context(request_dict, operation_model, api_params)
    
        service_id = self._service_model.service_id.hyphenize()
        handler, event_response = self.meta.events.emit_until_response(
            f'before-call.{service_id}.{operation_name}',
            model=operation_model,
            params=request_dict,
            request_signer=self._request_signer,
            context=request_context,
        )
    
        if event_response is not None:
            http, parsed_response = event_response
        else:
            maybe_compress_request(
                self.meta.config, request_dict, operation_model
            )
            apply_request_checksum(request_dict)
            http, parsed_response = self._make_request(
                operation_model, request_dict, request_context
            )
    
        self.meta.events.emit(
            f'after-call.{service_id}.{operation_name}',
            http_response=http,
            parsed=parsed_response,
            model=operation_model,
            context=request_context,
        )
    
        if http.status_code >= 300:
            error_info = parsed_response.get("Error", {})
            error_code = request_context.get(
                'error_code_override'
            ) or error_info.get("Code")
            error_class = self.exceptions.from_code(error_code)
>           raise error_class(parsed_response, operation_name)
E           botocore.exceptions.ClientError: An error occurred (SignatureDoesNotMatch) when calling the PutObject operation: The request signature we calculated does not match the signature you provided. Check your key and signing method.

.tox/py/lib/python3.9/site-packages/botocore/client.py:1078: ClientError
---------------------------- Captured stdout setup -----------------------------
Done with cleanup of buckets in tests.
Done with cleanup of buckets in tests.
Done with cleanup of buckets in tests.
--------------------------- Captured stdout teardown ---------------------------
Done with cleanup of buckets in tests.
Done with cleanup of buckets in tests.
Done with cleanup of buckets in tests.
__________________ test_object_create_bad_authorization_none ___________________

    @pytest.mark.auth_common
    # TODO: remove 'fails_on_rgw' and once we have learned how to remove the authorization header
    @pytest.mark.fails_on_rgw
    def test_object_create_bad_authorization_none():
>       e = _remove_header_create_bad_object('Authorization')

s3tests/functional/test_headers.py:286: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
s3tests/functional/test_headers.py:84: in _remove_header_create_bad_object
    e = assert_raises(ClientError, client.put_object, Bucket=bucket_name, Key=key_name, Body='bar')
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

excClass = <class 'botocore.exceptions.ClientError'>
callableObj = <bound method ClientCreator._create_api_method.<locals>._api_call of <botocore.client.S3 object at 0x7f9defd3d0d0>>
args = ()
kwargs = {'Body': 'bar', 'Bucket': 'yournamehere-al4ti6vy4wr2ctvr-17', 'Key': 'foo'}
excName = 'ClientError'

    def assert_raises(excClass, callableObj, *args, **kwargs):
        """
        Like unittest.TestCase.assertRaises, but returns the exception.
        """
        try:
            callableObj(*args, **kwargs)
        except excClass as e:
            return e
        else:
            if hasattr(excClass, '__name__'):
                excName = excClass.__name__
            else:
                excName = str(excClass)
>           raise AssertionError("%s not raised" % excName)
E           AssertionError: ClientError not raised

s3tests/functional/utils.py:19: AssertionError
---------------------------- Captured stdout setup -----------------------------
Done with cleanup of buckets in tests.
Done with cleanup of buckets in tests.
Done with cleanup of buckets in tests.
--------------------------- Captured stdout teardown ---------------------------
Done with cleanup of buckets in tests.
Done with cleanup of buckets in tests.
Done with cleanup of buckets in tests.
__________________ test_object_acl_create_contentlength_none ___________________

    @pytest.mark.auth_common
    # TODO: remove 'fails_on_rgw' and once we have learned how to remove the content-length header
    @pytest.mark.fails_on_rgw
    def test_object_acl_create_contentlength_none():
        bucket_name = get_new_bucket()
        client = get_client()
        client.put_object(Bucket=bucket_name, Key='foo', Body='bar')
    
        remove = 'Content-Length'
        def remove_header(**kwargs):
            if (remove in kwargs['params']['headers']):
                del kwargs['params']['headers'][remove]
    
        client.meta.events.register('before-call.s3.PutObjectAcl', remove_header)
>       client.put_object_acl(Bucket=bucket_name, Key='foo', ACL='public-read')

s3tests/functional/test_headers.py:311: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
.tox/py/lib/python3.9/site-packages/botocore/client.py:602: in _api_call
    return self._make_api_call(operation_name, kwargs)
.tox/py/lib/python3.9/site-packages/botocore/context.py:123: in wrapper
    return func(*args, **kwargs)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <botocore.client.S3 object at 0x7f9def76cc70>
operation_name = 'PutObjectAcl'
api_params = {'ACL': 'public-read', 'Bucket': 'yournamehere-al4ti6vy4wr2ctvr-19', 'Key': 'foo'}

    @with_current_context()
    def _make_api_call(self, operation_name, api_params):
        operation_model = self._service_model.operation_model(operation_name)
        service_name = self._service_model.service_name
        history_recorder.record(
            'API_CALL',
            {
                'service': service_name,
                'operation': operation_name,
                'params': api_params,
            },
        )
        if operation_model.deprecated:
            logger.debug(
                'Warning: %s.%s() is deprecated', service_name, operation_name
            )
        request_context = {
            'client_region': self.meta.region_name,
            'client_config': self.meta.config,
            'has_streaming_input': operation_model.has_streaming_input,
            'auth_type': operation_model.resolved_auth_type,
            'unsigned_payload': operation_model.unsigned_payload,
            'auth_options': self._service_model.metadata.get('auth'),
        }
    
        api_params = self._emit_api_params(
            api_params=api_params,
            operation_model=operation_model,
            context=request_context,
        )
        (
            endpoint_url,
            additional_headers,
            properties,
        ) = self._resolve_endpoint_ruleset(
            operation_model, api_params, request_context
        )
        if properties:
            # Pass arbitrary endpoint info with the Request
            # for use during construction.
            request_context['endpoint_properties'] = properties
        request_dict = self._convert_to_request_dict(
            api_params=api_params,
            operation_model=operation_model,
            endpoint_url=endpoint_url,
            context=request_context,
            headers=additional_headers,
        )
        resolve_checksum_context(request_dict, operation_model, api_params)
    
        service_id = self._service_model.service_id.hyphenize()
        handler, event_response = self.meta.events.emit_until_response(
            f'before-call.{service_id}.{operation_name}',
            model=operation_model,
            params=request_dict,
            request_signer=self._request_signer,
            context=request_context,
        )
    
        if event_response is not None:
            http, parsed_response = event_response
        else:
            maybe_compress_request(
                self.meta.config, request_dict, operation_model
            )
            apply_request_checksum(request_dict)
            http, parsed_response = self._make_request(
                operation_model, request_dict, request_context
            )
    
        self.meta.events.emit(
            f'after-call.{service_id}.{operation_name}',
            http_response=http,
            parsed=parsed_response,
            model=operation_model,
            context=request_context,
        )
    
        if http.status_code >= 300:
            error_info = parsed_response.get("Error", {})
            error_code = request_context.get(
                'error_code_override'
            ) or error_info.get("Code")
            error_class = self.exceptions.from_code(error_code)
>           raise error_class(parsed_response, operation_name)
E           botocore.exceptions.ClientError: An error occurred (AccessDenied) when calling the PutObjectAcl operation: User: arn:aws:iam::400180199233:root is not authorized to perform: s3:PutObjectAcl on resource: "arn:aws:s3:::yournamehere-al4ti6vy4wr2ctvr-19/foo" because public ACLs are prevented by the BlockPublicAcls setting in S3 Block Public Access.

.tox/py/lib/python3.9/site-packages/botocore/client.py:1078: ClientError
---------------------------- Captured stdout setup -----------------------------
Done with cleanup of buckets in tests.
Done with cleanup of buckets in tests.
Done with cleanup of buckets in tests.
--------------------------- Captured stdout teardown ---------------------------
Done with cleanup of buckets in tests.
Done with cleanup of buckets in tests.
Done with cleanup of buckets in tests.
__________________ test_bucket_create_bad_authorization_empty __________________

    @pytest.mark.auth_common
    # TODO: remove 'fails_on_rgw' and once we have learned how to manipulate the authorization header
    @pytest.mark.fails_on_rgw
    def test_bucket_create_bad_authorization_empty():
        headers = {'Authorization': ''}
>       e = _add_header_create_bad_bucket(headers)

s3tests/functional/test_headers.py:371: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
s3tests/functional/test_headers.py:114: in _add_header_create_bad_bucket
    e = assert_raises(ClientError, client.create_bucket, Bucket=bucket_name)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

excClass = <class 'botocore.exceptions.ClientError'>
callableObj = <bound method ClientCreator._create_api_method.<locals>._api_call of <botocore.client.S3 object at 0x7f9defa17790>>
args = (), kwargs = {'Bucket': 'yournamehere-al4ti6vy4wr2ctvr-26'}
excName = 'ClientError'

    def assert_raises(excClass, callableObj, *args, **kwargs):
        """
        Like unittest.TestCase.assertRaises, but returns the exception.
        """
        try:
            callableObj(*args, **kwargs)
        except excClass as e:
            return e
        else:
            if hasattr(excClass, '__name__'):
                excName = excClass.__name__
            else:
                excName = str(excClass)
>           raise AssertionError("%s not raised" % excName)
E           AssertionError: ClientError not raised

s3tests/functional/utils.py:19: AssertionError
---------------------------- Captured stdout setup -----------------------------
Done with cleanup of buckets in tests.
Done with cleanup of buckets in tests.
Done with cleanup of buckets in tests.
--------------------------- Captured stdout teardown ---------------------------
Done with cleanup of buckets in tests.
Done with cleanup of buckets in tests.
Done with cleanup of buckets in tests.
__________________ test_bucket_create_bad_authorization_none ___________________

    @pytest.mark.auth_common
    # TODO: remove 'fails_on_rgw' and once we have learned how to manipulate the authorization header
    @pytest.mark.fails_on_rgw
    def test_bucket_create_bad_authorization_none():
>       e = _remove_header_create_bad_bucket('Authorization')

s3tests/functional/test_headers.py:380: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
s3tests/functional/test_headers.py:149: in _remove_header_create_bad_bucket
    e = assert_raises(ClientError, client.create_bucket, Bucket=bucket_name)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

excClass = <class 'botocore.exceptions.ClientError'>
callableObj = <bound method ClientCreator._create_api_method.<locals>._api_call of <botocore.client.S3 object at 0x7f9def91ea90>>
args = (), kwargs = {'Bucket': 'yournamehere-al4ti6vy4wr2ctvr-27'}
excName = 'ClientError'

    def assert_raises(excClass, callableObj, *args, **kwargs):
        """
        Like unittest.TestCase.assertRaises, but returns the exception.
        """
        try:
            callableObj(*args, **kwargs)
        except excClass as e:
            return e
        else:
            if hasattr(excClass, '__name__'):
                excName = excClass.__name__
            else:
                excName = str(excClass)
>           raise AssertionError("%s not raised" % excName)
E           AssertionError: ClientError not raised

s3tests/functional/utils.py:19: AssertionError
---------------------------- Captured stdout setup -----------------------------
Done with cleanup of buckets in tests.
Done with cleanup of buckets in tests.
Done with cleanup of buckets in tests.
--------------------------- Captured stdout teardown ---------------------------
Done with cleanup of buckets in tests.
Done with cleanup of buckets in tests.
Done with cleanup of buckets in tests.
_____________ test_object_create_bad_authorization_incorrect_aws2 ______________

    @pytest.mark.auth_aws2
    # TODO: remove 'fails_on_rgw' and once we have learned how to manipulate the authorization header
    @pytest.mark.fails_on_rgw
    def test_object_create_bad_authorization_incorrect_aws2():
        v2_client = get_v2_client()
        headers = {'Authorization': 'AWS AKIAIGR7ZNNBHC5BKSUB:FWeDfwojDSdS2Ztmpfeubhd9isU='}
>       e = _add_header_create_bad_object(headers, v2_client)

s3tests/functional/test_headers.py:413: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
s3tests/functional/test_headers.py:47: in _add_header_create_bad_object
    e = assert_raises(ClientError, client.put_object, Bucket=bucket_name, Key=key_name, Body='bar')
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

excClass = <class 'botocore.exceptions.ClientError'>
callableObj = <bound method ClientCreator._create_api_method.<locals>._api_call of <botocore.client.S3 object at 0x7f9defa9bc70>>
args = ()
kwargs = {'Body': 'bar', 'Bucket': 'yournamehere-al4ti6vy4wr2ctvr-30', 'Key': 'foo'}
excName = 'ClientError'

    def assert_raises(excClass, callableObj, *args, **kwargs):
        """
        Like unittest.TestCase.assertRaises, but returns the exception.
        """
        try:
            callableObj(*args, **kwargs)
        except excClass as e:
            return e
        else:
            if hasattr(excClass, '__name__'):
                excName = excClass.__name__
            else:
                excName = str(excClass)
>           raise AssertionError("%s not raised" % excName)
E           AssertionError: ClientError not raised

s3tests/functional/utils.py:19: AssertionError
---------------------------- Captured stdout setup -----------------------------
Done with cleanup of buckets in tests.
Done with cleanup of buckets in tests.
Done with cleanup of buckets in tests.
--------------------------- Captured stdout teardown ---------------------------
Done with cleanup of buckets in tests.
Done with cleanup of buckets in tests.
Done with cleanup of buckets in tests.
______________ test_object_create_bad_authorization_invalid_aws2 _______________

    @pytest.mark.auth_aws2
    # TODO: remove 'fails_on_rgw' and once we have learned how to manipulate the authorization header
    @pytest.mark.fails_on_rgw
    def test_object_create_bad_authorization_invalid_aws2():
        v2_client = get_v2_client()
        headers = {'Authorization': 'AWS HAHAHA'}
>       e = _add_header_create_bad_object(headers, v2_client)

s3tests/functional/test_headers.py:424: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
s3tests/functional/test_headers.py:47: in _add_header_create_bad_object
    e = assert_raises(ClientError, client.put_object, Bucket=bucket_name, Key=key_name, Body='bar')
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

excClass = <class 'botocore.exceptions.ClientError'>
callableObj = <bound method ClientCreator._create_api_method.<locals>._api_call of <botocore.client.S3 object at 0x7f9def7ed370>>
args = ()
kwargs = {'Body': 'bar', 'Bucket': 'yournamehere-al4ti6vy4wr2ctvr-31', 'Key': 'foo'}
excName = 'ClientError'

    def assert_raises(excClass, callableObj, *args, **kwargs):
        """
        Like unittest.TestCase.assertRaises, but returns the exception.
        """
        try:
            callableObj(*args, **kwargs)
        except excClass as e:
            return e
        else:
            if hasattr(excClass, '__name__'):
                excName = excClass.__name__
            else:
                excName = str(excClass)
>           raise AssertionError("%s not raised" % excName)
E           AssertionError: ClientError not raised

s3tests/functional/utils.py:19: AssertionError
---------------------------- Captured stdout setup -----------------------------
Done with cleanup of buckets in tests.
Done with cleanup of buckets in tests.
Done with cleanup of buckets in tests.
--------------------------- Captured stdout teardown ---------------------------
Done with cleanup of buckets in tests.
Done with cleanup of buckets in tests.
Done with cleanup of buckets in tests.
____________________ test_object_create_bad_date_none_aws2 _____________________

    @pytest.mark.auth_aws2
    # TODO: remove 'fails_on_rgw' and once we have learned how to remove the date header
    @pytest.mark.fails_on_rgw
    def test_object_create_bad_date_none_aws2():
        v2_client = get_v2_client()
        remove = 'x-amz-date'
>       e = _remove_header_create_bad_object(remove, v2_client)

s3tests/functional/test_headers.py:467: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
s3tests/functional/test_headers.py:84: in _remove_header_create_bad_object
    e = assert_raises(ClientError, client.put_object, Bucket=bucket_name, Key=key_name, Body='bar')
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

excClass = <class 'botocore.exceptions.ClientError'>
callableObj = <bound method ClientCreator._create_api_method.<locals>._api_call of <botocore.client.S3 object at 0x7f9defa16580>>
args = ()
kwargs = {'Body': 'bar', 'Bucket': 'yournamehere-al4ti6vy4wr2ctvr-36', 'Key': 'foo'}
excName = 'ClientError'

    def assert_raises(excClass, callableObj, *args, **kwargs):
        """
        Like unittest.TestCase.assertRaises, but returns the exception.
        """
        try:
            callableObj(*args, **kwargs)
        except excClass as e:
            return e
        else:
            if hasattr(excClass, '__name__'):
                excName = excClass.__name__
            else:
                excName = str(excClass)
>           raise AssertionError("%s not raised" % excName)
E           AssertionError: ClientError not raised

s3tests/functional/utils.py:19: AssertionError
---------------------------- Captured stdout setup -----------------------------
Done with cleanup of buckets in tests.
Done with cleanup of buckets in tests.
Done with cleanup of buckets in tests.
--------------------------- Captured stdout teardown ---------------------------
Done with cleanup of buckets in tests.
Done with cleanup of buckets in tests.
Done with cleanup of buckets in tests.
______________ test_bucket_create_bad_authorization_invalid_aws2 _______________

    @pytest.mark.auth_aws2
    # TODO: remove 'fails_on_rgw' and once we have learned how to remove the date header
    @pytest.mark.fails_on_rgw
    def test_bucket_create_bad_authorization_invalid_aws2():
        v2_client = get_v2_client()
        headers = {'Authorization': 'AWS HAHAHA'}
        e = _add_header_create_bad_bucket(headers, v2_client)
        status, error_code = _get_status_and_error_code(e.response)
>       assert status == 400
E       assert 403 == 400

s3tests/functional/test_headers.py:507: AssertionError
---------------------------- Captured stdout setup -----------------------------
Done with cleanup of buckets in tests.
Done with cleanup of buckets in tests.
Done with cleanup of buckets in tests.
--------------------------- Captured stdout teardown ---------------------------
Done with cleanup of buckets in tests.
Done with cleanup of buckets in tests.
Done with cleanup of buckets in tests.
_____________________ test_bucket_create_bad_ua_empty_aws2 _____________________

    @pytest.mark.auth_aws2
    @pytest.mark.fails_on_rgw
    def test_bucket_create_bad_ua_empty_aws2():
        v2_client = get_v2_client()
        headers = {'User-Agent': ''}
>       _add_header_create_bucket(headers, v2_client)

s3tests/functional/test_headers.py:515: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
s3tests/functional/test_headers.py:99: in _add_header_create_bucket
    client.create_bucket(Bucket=bucket_name)
.tox/py/lib/python3.9/site-packages/botocore/client.py:602: in _api_call
    return self._make_api_call(operation_name, kwargs)
.tox/py/lib/python3.9/site-packages/botocore/context.py:123: in wrapper
    return func(*args, **kwargs)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <botocore.client.S3 object at 0x7f9def7a1250>
operation_name = 'CreateBucket'
api_params = {'Bucket': 'yournamehere-al4ti6vy4wr2ctvr-41'}

    @with_current_context()
    def _make_api_call(self, operation_name, api_params):
        operation_model = self._service_model.operation_model(operation_name)
        service_name = self._service_model.service_name
        history_recorder.record(
            'API_CALL',
            {
                'service': service_name,
                'operation': operation_name,
                'params': api_params,
            },
        )
        if operation_model.deprecated:
            logger.debug(
                'Warning: %s.%s() is deprecated', service_name, operation_name
            )
        request_context = {
            'client_region': self.meta.region_name,
            'client_config': self.meta.config,
            'has_streaming_input': operation_model.has_streaming_input,
            'auth_type': operation_model.resolved_auth_type,
            'unsigned_payload': operation_model.unsigned_payload,
            'auth_options': self._service_model.metadata.get('auth'),
        }
    
        api_params = self._emit_api_params(
            api_params=api_params,
            operation_model=operation_model,
            context=request_context,
        )
        (
            endpoint_url,
            additional_headers,
            properties,
        ) = self._resolve_endpoint_ruleset(
            operation_model, api_params, request_context
        )
        if properties:
            # Pass arbitrary endpoint info with the Request
            # for use during construction.
            request_context['endpoint_properties'] = properties
        request_dict = self._convert_to_request_dict(
            api_params=api_params,
            operation_model=operation_model,
            endpoint_url=endpoint_url,
            context=request_context,
            headers=additional_headers,
        )
        resolve_checksum_context(request_dict, operation_model, api_params)
    
        service_id = self._service_model.service_id.hyphenize()
        handler, event_response = self.meta.events.emit_until_response(
            f'before-call.{service_id}.{operation_name}',
            model=operation_model,
            params=request_dict,
            request_signer=self._request_signer,
            context=request_context,
        )
    
        if event_response is not None:
            http, parsed_response = event_response
        else:
            maybe_compress_request(
                self.meta.config, request_dict, operation_model
            )
            apply_request_checksum(request_dict)
            http, parsed_response = self._make_request(
                operation_model, request_dict, request_context
            )
    
        self.meta.events.emit(
            f'after-call.{service_id}.{operation_name}',
            http_response=http,
            parsed=parsed_response,
            model=operation_model,
            context=request_context,
        )
    
        if http.status_code >= 300:
            error_info = parsed_response.get("Error", {})
            error_code = request_context.get(
                'error_code_override'
            ) or error_info.get("Code")
            error_class = self.exceptions.from_code(error_code)
>           raise error_class(parsed_response, operation_name)
E           botocore.exceptions.ClientError: An error occurred (SignatureDoesNotMatch) when calling the CreateBucket operation: The request signature we calculated does not match the signature you provided. Check your key and signing method.

.tox/py/lib/python3.9/site-packages/botocore/client.py:1078: ClientError
---------------------------- Captured stdout setup -----------------------------
Done with cleanup of buckets in tests.
Done with cleanup of buckets in tests.
Done with cleanup of buckets in tests.
--------------------------- Captured stdout teardown ---------------------------
Done with cleanup of buckets in tests.
Done with cleanup of buckets in tests.
Done with cleanup of buckets in tests.
_____________________ test_bucket_create_bad_ua_none_aws2 ______________________

    @pytest.mark.auth_aws2
    @pytest.mark.fails_on_rgw
    def test_bucket_create_bad_ua_none_aws2():
        v2_client = get_v2_client()
        remove = 'User-Agent'
>       _remove_header_create_bucket(remove, v2_client)

s3tests/functional/test_headers.py:522: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
s3tests/functional/test_headers.py:132: in _remove_header_create_bucket
    client.create_bucket(Bucket=bucket_name)
.tox/py/lib/python3.9/site-packages/botocore/client.py:602: in _api_call
    return self._make_api_call(operation_name, kwargs)
.tox/py/lib/python3.9/site-packages/botocore/context.py:123: in wrapper
    return func(*args, **kwargs)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <botocore.client.S3 object at 0x7f9def86b4f0>
operation_name = 'CreateBucket'
api_params = {'Bucket': 'yournamehere-al4ti6vy4wr2ctvr-42'}

    @with_current_context()
    def _make_api_call(self, operation_name, api_params):
        operation_model = self._service_model.operation_model(operation_name)
        service_name = self._service_model.service_name
        history_recorder.record(
            'API_CALL',
            {
                'service': service_name,
                'operation': operation_name,
                'params': api_params,
            },
        )
        if operation_model.deprecated:
            logger.debug(
                'Warning: %s.%s() is deprecated', service_name, operation_name
            )
        request_context = {
            'client_region': self.meta.region_name,
            'client_config': self.meta.config,
            'has_streaming_input': operation_model.has_streaming_input,
            'auth_type': operation_model.resolved_auth_type,
            'unsigned_payload': operation_model.unsigned_payload,
            'auth_options': self._service_model.metadata.get('auth'),
        }
    
        api_params = self._emit_api_params(
            api_params=api_params,
            operation_model=operation_model,
            context=request_context,
        )
        (
            endpoint_url,
            additional_headers,
            properties,
        ) = self._resolve_endpoint_ruleset(
            operation_model, api_params, request_context
        )
        if properties:
            # Pass arbitrary endpoint info with the Request
            # for use during construction.
            request_context['endpoint_properties'] = properties
        request_dict = self._convert_to_request_dict(
            api_params=api_params,
            operation_model=operation_model,
            endpoint_url=endpoint_url,
            context=request_context,
            headers=additional_headers,
        )
        resolve_checksum_context(request_dict, operation_model, api_params)
    
        service_id = self._service_model.service_id.hyphenize()
        handler, event_response = self.meta.events.emit_until_response(
            f'before-call.{service_id}.{operation_name}',
            model=operation_model,
            params=request_dict,
            request_signer=self._request_signer,
            context=request_context,
        )
    
        if event_response is not None:
            http, parsed_response = event_response
        else:
            maybe_compress_request(
                self.meta.config, request_dict, operation_model
            )
            apply_request_checksum(request_dict)
            http, parsed_response = self._make_request(
                operation_model, request_dict, request_context
            )
    
        self.meta.events.emit(
            f'after-call.{service_id}.{operation_name}',
            http_response=http,
            parsed=parsed_response,
            model=operation_model,
            context=request_context,
        )
    
        if http.status_code >= 300:
            error_info = parsed_response.get("Error", {})
            error_code = request_context.get(
                'error_code_override'
            ) or error_info.get("Code")
            error_class = self.exceptions.from_code(error_code)
>           raise error_class(parsed_response, operation_name)
E           botocore.exceptions.ClientError: An error occurred (SignatureDoesNotMatch) when calling the CreateBucket operation: The request signature we calculated does not match the signature you provided. Check your key and signing method.

.tox/py/lib/python3.9/site-packages/botocore/client.py:1078: ClientError
---------------------------- Captured stdout setup -----------------------------
Done with cleanup of buckets in tests.
Done with cleanup of buckets in tests.
Done with cleanup of buckets in tests.
--------------------------- Captured stdout teardown ---------------------------
Done with cleanup of buckets in tests.
Done with cleanup of buckets in tests.
Done with cleanup of buckets in tests.
____________________ test_bucket_create_bad_date_none_aws2 _____________________

    @pytest.mark.auth_aws2
    # TODO: remove 'fails_on_rgw' and once we have learned how to remove the date header
    @pytest.mark.fails_on_rgw
    def test_bucket_create_bad_date_none_aws2():
        v2_client = get_v2_client()
        remove = 'x-amz-date'
        e = _remove_header_create_bad_bucket(remove, v2_client)
        status, error_code = _get_status_and_error_code(e.response)
        assert status == 403
>       assert error_code == 'AccessDenied'
E       AssertionError: assert 'SignatureDoesNotMatch' == 'AccessDenied'
E         
E         - AccessDenied
E         + SignatureDoesNotMatch

s3tests/functional/test_headers.py:551: AssertionError
---------------------------- Captured stdout setup -----------------------------
Done with cleanup of buckets in tests.
Done with cleanup of buckets in tests.
Done with cleanup of buckets in tests.
--------------------------- Captured stdout teardown ---------------------------
Done with cleanup of buckets in tests.
Done with cleanup of buckets in tests.
Done with cleanup of buckets in tests.
=============================== warnings summary ===============================
s3tests/functional/test_headers.py: 64 warnings
  /workspaces/s3-tests/.tox/py/lib/python3.9/site-packages/boto3/compat.py:89: PythonDeprecationWarning: Boto3 will no longer support Python 3.9 starting April 29, 2026. To continue receiving service updates, bug fixes, and security updates please upgrade to Python 3.10 or later. More information can be found here: https://aws.amazon.com/blogs/developer/python-support-policy-updates-for-aws-sdks-and-tools/
    warnings.warn(warning, PythonDeprecationWarning)

-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
=========================== short test summary info ============================
FAILED s3tests/functional/test_headers.py::test_object_create_bad_contentlength_empty
FAILED s3tests/functional/test_headers.py::test_object_create_bad_contentlength_none
FAILED s3tests/functional/test_headers.py::test_object_create_bad_authorization_empty
FAILED s3tests/functional/test_headers.py::test_object_create_date_and_amz_date
FAILED s3tests/functional/test_headers.py::test_object_create_amz_date_and_no_date
FAILED s3tests/functional/test_headers.py::test_object_create_bad_authorization_none
FAILED s3tests/functional/test_headers.py::test_object_acl_create_contentlength_none
FAILED s3tests/functional/test_headers.py::test_bucket_create_bad_authorization_empty
FAILED s3tests/functional/test_headers.py::test_bucket_create_bad_authorization_none
FAILED s3tests/functional/test_headers.py::test_object_create_bad_authorization_incorrect_aws2
FAILED s3tests/functional/test_headers.py::test_object_create_bad_authorization_invalid_aws2
FAILED s3tests/functional/test_headers.py::test_object_create_bad_date_none_aws2
FAILED s3tests/functional/test_headers.py::test_bucket_create_bad_authorization_invalid_aws2
FAILED s3tests/functional/test_headers.py::test_bucket_create_bad_ua_empty_aws2
FAILED s3tests/functional/test_headers.py::test_bucket_create_bad_ua_none_aws2
FAILED s3tests/functional/test_headers.py::test_bucket_create_bad_date_none_aws2
==== 16 failed, 32 passed, 993 deselected, 64 warnings in 221.12s (0:03:41) ====
ERROR: InvocationError for command /workspaces/s3-tests/.tox/py/bin/pytest -m 'auth_aws2 or auth_aws4 or auth_common' (exited with code 1)
___________________________________ summary ____________________________________
ERROR:   py: commands failed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant