]> git.apps.os.sepia.ceph.com Git - s3-tests.git/commitdiff
test_headers: add custom marks for auth_common/aws2/aws4
authorCasey Bodley <cbodley@redhat.com>
Wed, 25 Jan 2023 22:04:04 +0000 (17:04 -0500)
committerAli Maredia <amaredia@redhat.com>
Wed, 25 Jan 2023 23:04:31 +0000 (18:04 -0500)
Signed-off-by: Casey Bodley <cbodley@redhat.com>
(cherry picked from commit 7993dd02a53c83e5831fc62d954621f7aca92bf5)

pytest.ini
s3tests/functional/test_headers.py
s3tests_boto3/functional/test_headers.py

index f4f638e5f42a31227cf939cb369c27ed9a9fe3f6..0e3bcba2176a2888e73726cc178913768dc0a46c 100644 (file)
@@ -2,6 +2,9 @@
 markers =
     abac_test
     appendobject
+    auth_aws2
+    auth_aws4
+    auth_common
     bucket_policy
     bucket_encryption
     cloud_transition
index 85171a634c992ca300570d20e00578c9344e373b..b3eb5761b9ed67cb82969d8a1c357dc1053daf06 100644 (file)
@@ -168,18 +168,11 @@ def _setup_bad_object(headers=None, remove=None):
     _add_custom_headers(headers=headers, remove=remove)
     return bucket.new_key('foo')
 
-def tag(*tags):
-    def wrap(func):
-        for tag in tags:
-            setattr(func, tag, True)
-        return func
-    return wrap
-
 #
 # common tests
 #
 
-@tag('auth_common')
+@pytest.mark.auth_common
 @pytest.mark.fails_on_dbstore
 def test_object_create_bad_contentlength_none():
     key = _setup_bad_object(remove=('Content-Length',))
@@ -190,7 +183,7 @@ def test_object_create_bad_contentlength_none():
     assert e.error_code == 'MissingContentLength'
 
 
-@tag('auth_common')
+@pytest.mark.auth_common
 @pytest.mark.fails_on_rgw
 def test_object_create_bad_contentlength_mismatch_above():
     content = 'bar'
@@ -209,7 +202,7 @@ def test_object_create_bad_contentlength_mismatch_above():
     assert e.error_code == 'RequestTimeout'
 
 
-@tag('auth_common')
+@pytest.mark.auth_common
 @pytest.mark.fails_on_dbstore
 def test_object_create_bad_authorization_empty():
     key = _setup_bad_object({'Authorization': ''})
@@ -219,14 +212,14 @@ def test_object_create_bad_authorization_empty():
     assert e.reason == 'Forbidden'
     assert e.error_code == 'AccessDenied'
 
-@tag('auth_common')
+@pytest.mark.auth_common
 @pytest.mark.fails_on_dbstore
 def test_object_create_date_and_amz_date():
     date = formatdate(usegmt=True)
     key = _setup_bad_object({'Date': date, 'X-Amz-Date': date})
     key.set_contents_from_string('bar')
 
-@tag('auth_common')
+@pytest.mark.auth_common
 @pytest.mark.fails_on_dbstore
 def test_object_create_amz_date_and_no_date():
     date = formatdate(usegmt=True)
@@ -235,7 +228,7 @@ def test_object_create_amz_date_and_no_date():
 
 
 # the teardown is really messed up here. check it out
-@tag('auth_common')
+@pytest.mark.auth_common
 @pytest.mark.fails_on_dbstore
 def test_object_create_bad_authorization_none():
     key = _setup_bad_object(remove=('Authorization',))
@@ -246,14 +239,14 @@ def test_object_create_bad_authorization_none():
     assert e.error_code == 'AccessDenied'
 
 
-@tag('auth_common')
+@pytest.mark.auth_common
 @pytest.mark.fails_on_dbstore
 def test_bucket_create_contentlength_none():
     _add_custom_headers(remove=('Content-Length',))
     get_new_bucket()
 
 
-@tag('auth_common')
+@pytest.mark.auth_common
 @pytest.mark.fails_on_dbstore
 def test_object_acl_create_contentlength_none():
     bucket = get_new_bucket()
@@ -277,7 +270,7 @@ def _create_new_connection():
         )
     return TargetConnection(targets.main.default.conf, conn)
 
-@tag('auth_common')
+@pytest.mark.auth_common
 @pytest.mark.fails_on_rgw
 def test_bucket_create_bad_contentlength_empty():
     conn = _create_new_connection()
@@ -287,14 +280,14 @@ def test_bucket_create_bad_contentlength_empty():
     assert e.reason.lower() == 'bad request' # some proxies vary the case
 
 
-@tag('auth_common')
+@pytest.mark.auth_common
 @pytest.mark.fails_on_dbstore
 def test_bucket_create_bad_contentlength_none():
     _add_custom_headers(remove=('Content-Length',))
     bucket = get_new_bucket()
 
 
-@tag('auth_common')
+@pytest.mark.auth_common
 @pytest.mark.fails_on_dbstore
 def test_bucket_create_bad_authorization_empty():
     _add_custom_headers({'Authorization': ''})
@@ -305,7 +298,7 @@ def test_bucket_create_bad_authorization_empty():
 
 
 # the teardown is really messed up here. check it out
-@tag('auth_common')
+@pytest.mark.auth_common
 @pytest.mark.fails_on_dbstore
 def test_bucket_create_bad_authorization_none():
     _add_custom_headers(remove=('Authorization',))
@@ -318,7 +311,7 @@ def test_bucket_create_bad_authorization_none():
 # AWS2 specific tests
 #
 
-@tag('auth_aws2')
+@pytest.mark.auth_aws2
 @pytest.mark.fails_on_dbstore
 def test_object_create_bad_contentlength_mismatch_below_aws2():
     check_aws2_support()
@@ -331,7 +324,7 @@ def test_object_create_bad_contentlength_mismatch_below_aws2():
     assert e.error_code == 'BadDigest'
 
 
-@tag('auth_aws2')
+@pytest.mark.auth_aws2
 @pytest.mark.fails_on_dbstore
 def test_object_create_bad_authorization_incorrect_aws2():
     check_aws2_support()
@@ -342,7 +335,7 @@ def test_object_create_bad_authorization_incorrect_aws2():
     assert e.error_code in ('AccessDenied', 'SignatureDoesNotMatch', 'InvalidAccessKeyId')
 
 
-@tag('auth_aws2')
+@pytest.mark.auth_aws2
 @pytest.mark.fails_on_dbstore
 def test_object_create_bad_authorization_invalid_aws2():
     check_aws2_support()
@@ -352,7 +345,7 @@ def test_object_create_bad_authorization_invalid_aws2():
     assert e.reason.lower() == 'bad request' # some proxies vary the case
     assert e.error_code == 'InvalidArgument'
 
-@tag('auth_aws2')
+@pytest.mark.auth_aws2
 @pytest.mark.fails_on_dbstore
 def test_object_create_bad_date_none_aws2():
     check_aws2_support()
@@ -363,7 +356,7 @@ def test_object_create_bad_date_none_aws2():
     assert e.error_code == 'AccessDenied'
 
 
-@tag('auth_aws2')
+@pytest.mark.auth_aws2
 def test_bucket_create_bad_authorization_invalid_aws2():
     check_aws2_support()
     _add_custom_headers({'Authorization': 'AWS HAHAHA'})
@@ -372,7 +365,7 @@ def test_bucket_create_bad_authorization_invalid_aws2():
     assert e.reason.lower() == 'bad request' # some proxies vary the case
     assert e.error_code == 'InvalidArgument'
 
-@tag('auth_aws2')
+@pytest.mark.auth_aws2
 @pytest.mark.fails_on_dbstore
 def test_bucket_create_bad_date_none_aws2():
     check_aws2_support()
@@ -395,7 +388,7 @@ def check_aws2_support():
         pytest.skip('sigv2 tests disabled by S3_USE_SIGV4')
 
 
-@tag('auth_aws4')
+@pytest.mark.auth_aws4
 def test_object_create_bad_md5_invalid_garbage_aws4():
     check_aws4_support()
     key = _setup_bad_object({'Content-MD5':'AWS4 HAHAHA'})
@@ -406,7 +399,7 @@ def test_object_create_bad_md5_invalid_garbage_aws4():
     assert e.error_code == 'InvalidDigest'
 
 
-@tag('auth_aws4')
+@pytest.mark.auth_aws4
 def test_object_create_bad_contentlength_mismatch_below_aws4():
     check_aws4_support()
     content = 'bar'
@@ -419,7 +412,7 @@ def test_object_create_bad_contentlength_mismatch_below_aws4():
     assert e.error_code == 'XAmzContentSHA256Mismatch'
 
 
-@tag('auth_aws4')
+@pytest.mark.auth_aws4
 def test_object_create_bad_authorization_incorrect_aws4():
     check_aws4_support()
     key = _setup_bad_object({'Authorization': 'AWS4-HMAC-SHA256 Credential=AKIAIGR7ZNNBHC5BKSUB/20150930/us-east-1/s3/aws4_request,SignedHeaders=host;user-agent,Signature=FWeDfwojDSdS2Ztmpfeubhd9isU='})
@@ -430,7 +423,7 @@ def test_object_create_bad_authorization_incorrect_aws4():
     assert e.error_code in ('AccessDenied', 'SignatureDoesNotMatch', 'InvalidAccessKeyId')
 
 
-@tag('auth_aws4')
+@pytest.mark.auth_aws4
 def test_object_create_bad_authorization_invalid_aws4():
     check_aws4_support()
     key = _setup_bad_object({'Authorization': 'AWS4-HMAC-SHA256 Credential=HAHAHA'})
@@ -441,7 +434,7 @@ def test_object_create_bad_authorization_invalid_aws4():
     assert e.error_code in ('AuthorizationHeaderMalformed', 'InvalidArgument')
 
 
-@tag('auth_aws4')
+@pytest.mark.auth_aws4
 def test_object_create_bad_ua_empty_aws4():
     check_aws4_support()
     key = _setup_bad_object({'User-Agent': ''})
@@ -452,7 +445,7 @@ def test_object_create_bad_ua_empty_aws4():
     assert e.error_code == 'SignatureDoesNotMatch'
 
 
-@tag('auth_aws4')
+@pytest.mark.auth_aws4
 def test_object_create_bad_ua_none_aws4():
     check_aws4_support()
     key = _setup_bad_object(remove=('User-Agent',))
@@ -463,14 +456,14 @@ def test_object_create_bad_ua_none_aws4():
     assert e.error_code == 'SignatureDoesNotMatch'
 
 
-@tag('auth_aws4')
+@pytest.mark.auth_aws4
 def test_object_create_bad_date_invalid_aws4():
     check_aws4_support()
     key = _setup_bad_object({'Date': 'Bad Date'})
     key.set_contents_from_string('bar')
 
 
-@tag('auth_aws4')
+@pytest.mark.auth_aws4
 def test_object_create_bad_amz_date_invalid_aws4():
     check_aws4_support()
     key = _setup_bad_object({'X-Amz-Date': 'Bad Date'})
@@ -481,14 +474,14 @@ def test_object_create_bad_amz_date_invalid_aws4():
     assert e.error_code in ('AccessDenied', 'SignatureDoesNotMatch')
 
 
-@tag('auth_aws4')
+@pytest.mark.auth_aws4
 def test_object_create_bad_date_empty_aws4():
     check_aws4_support()
     key = _setup_bad_object({'Date': ''})
     key.set_contents_from_string('bar')
 
 
-@tag('auth_aws4')
+@pytest.mark.auth_aws4
 def test_object_create_bad_amz_date_empty_aws4():
     check_aws4_support()
     key = _setup_bad_object({'X-Amz-Date': ''})
@@ -499,14 +492,14 @@ def test_object_create_bad_amz_date_empty_aws4():
     assert e.error_code in ('AccessDenied', 'SignatureDoesNotMatch')
 
 
-@tag('auth_aws4')
+@pytest.mark.auth_aws4
 def test_object_create_bad_date_none_aws4():
     check_aws4_support()
     key = _setup_bad_object(remove=('Date',))
     key.set_contents_from_string('bar')
 
 
-@tag('auth_aws4')
+@pytest.mark.auth_aws4
 def test_object_create_bad_amz_date_none_aws4():
     check_aws4_support()
     key = _setup_bad_object(remove=('X-Amz-Date',))
@@ -517,14 +510,14 @@ def test_object_create_bad_amz_date_none_aws4():
     assert e.error_code in ('AccessDenied', 'SignatureDoesNotMatch')
 
 
-@tag('auth_aws4')
+@pytest.mark.auth_aws4
 def test_object_create_bad_date_before_today_aws4():
     check_aws4_support()
     key = _setup_bad_object({'Date': 'Tue, 07 Jul 2010 21:53:04 GMT'})
     key.set_contents_from_string('bar')
 
 
-@tag('auth_aws4')
+@pytest.mark.auth_aws4
 def test_object_create_bad_amz_date_before_today_aws4():
     check_aws4_support()
     key = _setup_bad_object({'X-Amz-Date': '20100707T215304Z'})
@@ -535,14 +528,14 @@ def test_object_create_bad_amz_date_before_today_aws4():
     assert e.error_code in ('RequestTimeTooSkewed', 'SignatureDoesNotMatch')
 
 
-@tag('auth_aws4')
+@pytest.mark.auth_aws4
 def test_object_create_bad_date_after_today_aws4():
     check_aws4_support()
     key = _setup_bad_object({'Date': 'Tue, 07 Jul 2030 21:53:04 GMT'})
     key.set_contents_from_string('bar')
 
 
-@tag('auth_aws4')
+@pytest.mark.auth_aws4
 def test_object_create_bad_amz_date_after_today_aws4():
     check_aws4_support()
     key = _setup_bad_object({'X-Amz-Date': '20300707T215304Z'})
@@ -553,14 +546,14 @@ def test_object_create_bad_amz_date_after_today_aws4():
     assert e.error_code in ('RequestTimeTooSkewed', 'SignatureDoesNotMatch')
 
 
-@tag('auth_aws4')
+@pytest.mark.auth_aws4
 def test_object_create_bad_date_before_epoch_aws4():
     check_aws4_support()
     key = _setup_bad_object({'Date': 'Tue, 07 Jul 1950 21:53:04 GMT'})
     key.set_contents_from_string('bar')
 
 
-@tag('auth_aws4')
+@pytest.mark.auth_aws4
 def test_object_create_bad_amz_date_before_epoch_aws4():
     check_aws4_support()
     key = _setup_bad_object({'X-Amz-Date': '19500707T215304Z'})
@@ -571,14 +564,14 @@ def test_object_create_bad_amz_date_before_epoch_aws4():
     assert e.error_code in ('AccessDenied', 'SignatureDoesNotMatch')
 
 
-@tag('auth_aws4')
+@pytest.mark.auth_aws4
 def test_object_create_bad_date_after_end_aws4():
     check_aws4_support()
     key = _setup_bad_object({'Date': 'Tue, 07 Jul 9999 21:53:04 GMT'})
     key.set_contents_from_string('bar')
 
 
-@tag('auth_aws4')
+@pytest.mark.auth_aws4
 def test_object_create_bad_amz_date_after_end_aws4():
     check_aws4_support()
     key = _setup_bad_object({'X-Amz-Date': '99990707T215304Z'})
@@ -589,7 +582,7 @@ def test_object_create_bad_amz_date_after_end_aws4():
     assert e.error_code in ('RequestTimeTooSkewed', 'SignatureDoesNotMatch')
 
 
-@tag('auth_aws4')
+@pytest.mark.auth_aws4
 def test_object_create_missing_signed_custom_header_aws4():
     check_aws4_support()
     method='PUT'
@@ -615,7 +608,7 @@ def test_object_create_missing_signed_custom_header_aws4():
     assert res.reason == 'Forbidden'
 
 
-@tag('auth_aws4')
+@pytest.mark.auth_aws4
 def test_object_create_missing_signed_header_aws4():
     check_aws4_support()
     method='PUT'
@@ -642,7 +635,7 @@ def test_object_create_missing_signed_header_aws4():
     assert res.reason == 'Forbidden'
 
 
-@tag('auth_aws4')
+@pytest.mark.auth_aws4
 def test_bucket_create_bad_authorization_invalid_aws4():
     check_aws4_support()
     _add_custom_headers({'Authorization': 'AWS4 HAHAHA'})
@@ -653,7 +646,7 @@ def test_bucket_create_bad_authorization_invalid_aws4():
     assert e.error_code == 'InvalidArgument'
 
 
-@tag('auth_aws4')
+@pytest.mark.auth_aws4
 def test_bucket_create_bad_ua_empty_aws4():
     check_aws4_support()
     _add_custom_headers({'User-Agent': ''})
@@ -663,7 +656,7 @@ def test_bucket_create_bad_ua_empty_aws4():
     assert e.reason == 'Forbidden'
     assert e.error_code == 'SignatureDoesNotMatch'
 
-@tag('auth_aws4')
+@pytest.mark.auth_aws4
 def test_bucket_create_bad_ua_none_aws4():
     check_aws4_support()
     _add_custom_headers(remove=('User-Agent',))
@@ -674,14 +667,14 @@ def test_bucket_create_bad_ua_none_aws4():
     assert e.error_code == 'SignatureDoesNotMatch'
 
 
-@tag('auth_aws4')
+@pytest.mark.auth_aws4
 def test_bucket_create_bad_date_invalid_aws4():
     check_aws4_support()
     _add_custom_headers({'Date': 'Bad Date'})
     get_new_bucket()
 
 
-@tag('auth_aws4')
+@pytest.mark.auth_aws4
 def test_bucket_create_bad_amz_date_invalid_aws4():
     check_aws4_support()
     _add_custom_headers({'X-Amz-Date': 'Bad Date'})
@@ -692,14 +685,14 @@ def test_bucket_create_bad_amz_date_invalid_aws4():
     assert e.error_code in ('AccessDenied', 'SignatureDoesNotMatch')
 
 
-@tag('auth_aws4')
+@pytest.mark.auth_aws4
 def test_bucket_create_bad_date_empty_aws4():
     check_aws4_support()
     _add_custom_headers({'Date': ''})
     get_new_bucket()
 
 
-@tag('auth_aws4')
+@pytest.mark.auth_aws4
 def test_bucket_create_bad_amz_date_empty_aws4():
     check_aws4_support()
     _add_custom_headers({'X-Amz-Date': ''})
@@ -709,14 +702,14 @@ def test_bucket_create_bad_amz_date_empty_aws4():
     assert e.reason == 'Forbidden'
     assert e.error_code in ('AccessDenied', 'SignatureDoesNotMatch')
 
-@tag('auth_aws4')
+@pytest.mark.auth_aws4
 def test_bucket_create_bad_date_none_aws4():
     check_aws4_support()
     _add_custom_headers(remove=('Date',))
     get_new_bucket()
 
 
-@tag('auth_aws4')
+@pytest.mark.auth_aws4
 def test_bucket_create_bad_amz_date_none_aws4():
     check_aws4_support()
     _add_custom_headers(remove=('X-Amz-Date',))
@@ -727,14 +720,14 @@ def test_bucket_create_bad_amz_date_none_aws4():
     assert e.error_code in ('AccessDenied', 'SignatureDoesNotMatch')
 
 
-@tag('auth_aws4')
+@pytest.mark.auth_aws4
 def test_bucket_create_bad_date_before_today_aws4():
     check_aws4_support()
     _add_custom_headers({'Date': 'Tue, 07 Jul 2010 21:53:04 GMT'})
     get_new_bucket()
 
 
-@tag('auth_aws4')
+@pytest.mark.auth_aws4
 def test_bucket_create_bad_amz_date_before_today_aws4():
     check_aws4_support()
     _add_custom_headers({'X-Amz-Date': '20100707T215304Z'})
@@ -745,14 +738,14 @@ def test_bucket_create_bad_amz_date_before_today_aws4():
     assert e.error_code in ('RequestTimeTooSkewed', 'SignatureDoesNotMatch')
 
 
-@tag('auth_aws4')
+@pytest.mark.auth_aws4
 def test_bucket_create_bad_date_after_today_aws4():
     check_aws4_support()
     _add_custom_headers({'Date': 'Tue, 07 Jul 2030 21:53:04 GMT'})
     get_new_bucket()
 
 
-@tag('auth_aws4')
+@pytest.mark.auth_aws4
 def test_bucket_create_bad_amz_date_after_today_aws4():
     check_aws4_support()
     _add_custom_headers({'X-Amz-Date': '20300707T215304Z'})
@@ -763,14 +756,14 @@ def test_bucket_create_bad_amz_date_after_today_aws4():
     assert e.error_code in ('RequestTimeTooSkewed', 'SignatureDoesNotMatch')
 
 
-@tag('auth_aws4')
+@pytest.mark.auth_aws4
 def test_bucket_create_bad_date_before_epoch_aws4():
     check_aws4_support()
     _add_custom_headers({'Date': 'Tue, 07 Jul 1950 21:53:04 GMT'})
     get_new_bucket()
 
 
-@tag('auth_aws4')
+@pytest.mark.auth_aws4
 def test_bucket_create_bad_amz_date_before_epoch_aws4():
     check_aws4_support()
     _add_custom_headers({'X-Amz-Date': '19500707T215304Z'})
index 4573d7299286e8c46e8768210a04aa76ffcad5e2..66cabe56036a57d4341d9eb3515cf85e233f68f4 100644 (file)
@@ -149,63 +149,56 @@ def _remove_header_create_bad_bucket(remove, client=None):
 
     return e
 
-def tag(*tags):
-    def wrap(func):
-        for tag in tags:
-            setattr(func, tag, True)
-        return func
-    return wrap
-
 #
 # common tests
 #
 
-@tag('auth_common')
+@pytest.mark.auth_common
 def test_object_create_bad_md5_invalid_short():
     e = _add_header_create_bad_object({'Content-MD5':'YWJyYWNhZGFicmE='})
     status, error_code = _get_status_and_error_code(e.response)
     assert status == 400
     assert error_code == 'InvalidDigest'
 
-@tag('auth_common')
+@pytest.mark.auth_common
 def test_object_create_bad_md5_bad():
     e = _add_header_create_bad_object({'Content-MD5':'rL0Y20xC+Fzt72VPzMSk2A=='})
     status, error_code = _get_status_and_error_code(e.response)
     assert status == 400
     assert error_code == 'BadDigest'
 
-@tag('auth_common')
+@pytest.mark.auth_common
 def test_object_create_bad_md5_empty():
     e = _add_header_create_bad_object({'Content-MD5':''})
     status, error_code = _get_status_and_error_code(e.response)
     assert status == 400
     assert error_code == 'InvalidDigest'
 
-@tag('auth_common')
+@pytest.mark.auth_common
 def test_object_create_bad_md5_none():
     bucket_name, key_name = _remove_header_create_object('Content-MD5')
     client = get_client()
     client.put_object(Bucket=bucket_name, Key=key_name, Body='bar')
 
-@tag('auth_common')
+@pytest.mark.auth_common
 def test_object_create_bad_expect_mismatch():
     bucket_name, key_name = _add_header_create_object({'Expect': 200})
     client = get_client()
     client.put_object(Bucket=bucket_name, Key=key_name, Body='bar')
 
-@tag('auth_common')
+@pytest.mark.auth_common
 def test_object_create_bad_expect_empty():
     bucket_name, key_name = _add_header_create_object({'Expect': ''})
     client = get_client()
     client.put_object(Bucket=bucket_name, Key=key_name, Body='bar')
 
-@tag('auth_common')
+@pytest.mark.auth_common
 def test_object_create_bad_expect_none():
     bucket_name, key_name = _remove_header_create_object('Expect')
     client = get_client()
     client.put_object(Bucket=bucket_name, Key=key_name, Body='bar')
 
-@tag('auth_common')
+@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():
@@ -213,7 +206,7 @@ def test_object_create_bad_contentlength_empty():
     status, error_code = _get_status_and_error_code(e.response)
     assert status == 400
 
-@tag('auth_common')
+@pytest.mark.auth_common
 @pytest.mark.fails_on_mod_proxy_fcgi
 def test_object_create_bad_contentlength_negative():
     client = get_client()
@@ -223,7 +216,7 @@ def test_object_create_bad_contentlength_negative():
     status = _get_status(e.response)
     assert status == 400
 
-@tag('auth_common')
+@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():
@@ -233,20 +226,20 @@ def test_object_create_bad_contentlength_none():
     assert status == 411
     assert error_code == 'MissingContentLength'
 
-@tag('auth_common')
+@pytest.mark.auth_common
 def test_object_create_bad_contenttype_invalid():
     bucket_name, key_name = _add_header_create_object({'Content-Type': 'text/plain'})
     client = get_client()
     client.put_object(Bucket=bucket_name, Key=key_name, Body='bar')
 
-@tag('auth_common')
+@pytest.mark.auth_common
 def test_object_create_bad_contenttype_empty():
     client = get_client()
     key_name = 'foo'
     bucket_name = get_new_bucket()
     client.put_object(Bucket=bucket_name, Key=key_name, Body='bar', ContentType='')
 
-@tag('auth_common')
+@pytest.mark.auth_common
 def test_object_create_bad_contenttype_none():
     bucket_name = get_new_bucket()
     key_name = 'foo'
@@ -255,7 +248,7 @@ def test_object_create_bad_contenttype_none():
     client.put_object(Bucket=bucket_name, Key=key_name, Body='bar')
 
 
-@tag('auth_common')
+@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():
@@ -263,7 +256,7 @@ def test_object_create_bad_authorization_empty():
     status, error_code = _get_status_and_error_code(e.response)
     assert status == 403
 
-@tag('auth_common')
+@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():
@@ -272,7 +265,7 @@ def test_object_create_date_and_amz_date():
     client = get_client()
     client.put_object(Bucket=bucket_name, Key=key_name, Body='bar')
 
-@tag('auth_common')
+@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():
@@ -282,7 +275,7 @@ def test_object_create_amz_date_and_no_date():
     client.put_object(Bucket=bucket_name, Key=key_name, Body='bar')
 
 # the teardown is really messed up here. check it out
-@tag('auth_common')
+@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():
@@ -290,14 +283,14 @@ def test_object_create_bad_authorization_none():
     status, error_code = _get_status_and_error_code(e.response)
     assert status == 403
 
-@tag('auth_common')
+@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_bucket_create_contentlength_none():
     remove = 'Content-Length'
     _remove_header_create_bucket(remove)
 
-@tag('auth_common')
+@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():
@@ -313,7 +306,7 @@ def test_object_acl_create_contentlength_none():
     client.meta.events.register('before-call.s3.PutObjectAcl', remove_header)
     client.put_object_acl(Bucket=bucket_name, Key='foo', ACL='public-read')
 
-@tag('auth_common')
+@pytest.mark.auth_common
 def test_bucket_put_bad_canned_acl():
     bucket_name = get_new_bucket()
     client = get_client()
@@ -326,7 +319,7 @@ def test_bucket_put_bad_canned_acl():
     status = _get_status(e.response)
     assert status == 400
 
-@tag('auth_common')
+@pytest.mark.auth_common
 def test_bucket_create_bad_expect_mismatch():
     bucket_name = get_new_bucket_name()
     client = get_client()
@@ -336,12 +329,12 @@ def test_bucket_create_bad_expect_mismatch():
     client.meta.events.register('before-call.s3.CreateBucket', add_headers)
     client.create_bucket(Bucket=bucket_name)
 
-@tag('auth_common')
+@pytest.mark.auth_common
 def test_bucket_create_bad_expect_empty():
     headers = {'Expect': ''}
     _add_header_create_bucket(headers)
 
-@tag('auth_common')
+@pytest.mark.auth_common
 # TODO: The request isn't even making it to the RGW past the frontend
 # This test had 'fails_on_rgw' before the move to boto3
 @pytest.mark.fails_on_rgw
@@ -351,7 +344,7 @@ def test_bucket_create_bad_contentlength_empty():
     status, error_code = _get_status_and_error_code(e.response)
     assert status == 400
 
-@tag('auth_common')
+@pytest.mark.auth_common
 @pytest.mark.fails_on_mod_proxy_fcgi
 def test_bucket_create_bad_contentlength_negative():
     headers = {'Content-Length': '-1'}
@@ -359,14 +352,14 @@ def test_bucket_create_bad_contentlength_negative():
     status = _get_status(e.response)
     assert status == 400
 
-@tag('auth_common')
+@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_bucket_create_bad_contentlength_none():
     remove = 'Content-Length'
     _remove_header_create_bucket(remove)
 
-@tag('auth_common')
+@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():
@@ -376,7 +369,7 @@ def test_bucket_create_bad_authorization_empty():
     assert status == 403
     assert error_code == 'AccessDenied'
 
-@tag('auth_common')
+@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():
@@ -385,7 +378,7 @@ def test_bucket_create_bad_authorization_none():
     assert status == 403
     assert error_code == 'AccessDenied'
 
-@tag('auth_aws2')
+@pytest.mark.auth_aws2
 def test_object_create_bad_md5_invalid_garbage_aws2():
     v2_client = get_v2_client()
     headers = {'Content-MD5': 'AWS HAHAHA'}
@@ -394,7 +387,7 @@ def test_object_create_bad_md5_invalid_garbage_aws2():
     assert status == 400
     assert error_code == 'InvalidDigest'
 
-@tag('auth_aws2')
+@pytest.mark.auth_aws2
 # TODO: remove 'fails_on_rgw' and once we have learned how to manipulate the Content-Length header
 @pytest.mark.fails_on_rgw
 def test_object_create_bad_contentlength_mismatch_below_aws2():
@@ -407,7 +400,7 @@ def test_object_create_bad_contentlength_mismatch_below_aws2():
     assert status == 400
     assert error_code == 'BadDigest'
 
-@tag('auth_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():
@@ -418,7 +411,7 @@ def test_object_create_bad_authorization_incorrect_aws2():
     assert status == 403
     assert error_code == 'InvalidDigest'
 
-@tag('auth_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():
@@ -429,21 +422,21 @@ def test_object_create_bad_authorization_invalid_aws2():
     assert status == 400
     assert error_code == 'InvalidArgument'
 
-@tag('auth_aws2')
+@pytest.mark.auth_aws2
 def test_object_create_bad_ua_empty_aws2():
     v2_client = get_v2_client()
     headers = {'User-Agent': ''}
     bucket_name, key_name = _add_header_create_object(headers, v2_client)
     v2_client.put_object(Bucket=bucket_name, Key=key_name, Body='bar')
 
-@tag('auth_aws2')
+@pytest.mark.auth_aws2
 def test_object_create_bad_ua_none_aws2():
     v2_client = get_v2_client()
     remove = 'User-Agent'
     bucket_name, key_name = _remove_header_create_object(remove, v2_client)
     v2_client.put_object(Bucket=bucket_name, Key=key_name, Body='bar')
 
-@tag('auth_aws2')
+@pytest.mark.auth_aws2
 def test_object_create_bad_date_invalid_aws2():
     v2_client = get_v2_client()
     headers = {'x-amz-date': 'Bad Date'}
@@ -452,7 +445,7 @@ def test_object_create_bad_date_invalid_aws2():
     assert status == 403
     assert error_code == 'AccessDenied'
 
-@tag('auth_aws2')
+@pytest.mark.auth_aws2
 def test_object_create_bad_date_empty_aws2():
     v2_client = get_v2_client()
     headers = {'x-amz-date': ''}
@@ -461,7 +454,7 @@ def test_object_create_bad_date_empty_aws2():
     assert status == 403
     assert error_code == 'AccessDenied'
 
-@tag('auth_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():
@@ -472,7 +465,7 @@ def test_object_create_bad_date_none_aws2():
     assert status == 403
     assert error_code == 'AccessDenied'
 
-@tag('auth_aws2')
+@pytest.mark.auth_aws2
 def test_object_create_bad_date_before_today_aws2():
     v2_client = get_v2_client()
     headers = {'x-amz-date': 'Tue, 07 Jul 2010 21:53:04 GMT'}
@@ -481,7 +474,7 @@ def test_object_create_bad_date_before_today_aws2():
     assert status == 403
     assert error_code == 'RequestTimeTooSkewed'
 
-@tag('auth_aws2')
+@pytest.mark.auth_aws2
 def test_object_create_bad_date_before_epoch_aws2():
     v2_client = get_v2_client()
     headers = {'x-amz-date': 'Tue, 07 Jul 1950 21:53:04 GMT'}
@@ -490,7 +483,7 @@ def test_object_create_bad_date_before_epoch_aws2():
     assert status == 403
     assert error_code == 'AccessDenied'
 
-@tag('auth_aws2')
+@pytest.mark.auth_aws2
 def test_object_create_bad_date_after_end_aws2():
     v2_client = get_v2_client()
     headers = {'x-amz-date': 'Tue, 07 Jul 9999 21:53:04 GMT'}
@@ -499,7 +492,7 @@ def test_object_create_bad_date_after_end_aws2():
     assert status == 403
     assert error_code == 'RequestTimeTooSkewed'
 
-@tag('auth_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():
@@ -510,19 +503,19 @@ def test_bucket_create_bad_authorization_invalid_aws2():
     assert status == 400
     assert error_code == 'InvalidArgument'
 
-@tag('auth_aws2')
+@pytest.mark.auth_aws2
 def test_bucket_create_bad_ua_empty_aws2():
     v2_client = get_v2_client()
     headers = {'User-Agent': ''}
     _add_header_create_bucket(headers, v2_client)
 
-@tag('auth_aws2')
+@pytest.mark.auth_aws2
 def test_bucket_create_bad_ua_none_aws2():
     v2_client = get_v2_client()
     remove = 'User-Agent'
     _remove_header_create_bucket(remove, v2_client)
 
-@tag('auth_aws2')
+@pytest.mark.auth_aws2
 def test_bucket_create_bad_date_invalid_aws2():
     v2_client = get_v2_client()
     headers = {'x-amz-date': 'Bad Date'}
@@ -531,7 +524,7 @@ def test_bucket_create_bad_date_invalid_aws2():
     assert status == 403
     assert error_code == 'AccessDenied'
 
-@tag('auth_aws2')
+@pytest.mark.auth_aws2
 def test_bucket_create_bad_date_empty_aws2():
     v2_client = get_v2_client()
     headers = {'x-amz-date': ''}
@@ -540,7 +533,7 @@ def test_bucket_create_bad_date_empty_aws2():
     assert status == 403
     assert error_code == 'AccessDenied'
 
-@tag('auth_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():
@@ -551,7 +544,7 @@ def test_bucket_create_bad_date_none_aws2():
     assert status == 403
     assert error_code == 'AccessDenied'
 
-@tag('auth_aws2')
+@pytest.mark.auth_aws2
 def test_bucket_create_bad_date_before_today_aws2():
     v2_client = get_v2_client()
     headers = {'x-amz-date': 'Tue, 07 Jul 2010 21:53:04 GMT'}
@@ -560,7 +553,7 @@ def test_bucket_create_bad_date_before_today_aws2():
     assert status == 403
     assert error_code == 'RequestTimeTooSkewed'
 
-@tag('auth_aws2')
+@pytest.mark.auth_aws2
 def test_bucket_create_bad_date_after_today_aws2():
     v2_client = get_v2_client()
     headers = {'x-amz-date': 'Tue, 07 Jul 2030 21:53:04 GMT'}
@@ -569,7 +562,7 @@ def test_bucket_create_bad_date_after_today_aws2():
     assert status == 403
     assert error_code == 'RequestTimeTooSkewed'
 
-@tag('auth_aws2')
+@pytest.mark.auth_aws2
 def test_bucket_create_bad_date_before_epoch_aws2():
     v2_client = get_v2_client()
     headers = {'x-amz-date': 'Tue, 07 Jul 1950 21:53:04 GMT'}