From d98d7956c10d1a356e7856a92755d2c31141f57a Mon Sep 17 00:00:00 2001 From: "Robin H. Johnson" Date: Wed, 7 Oct 2015 12:31:31 -0700 Subject: [PATCH] Improve proxy error support: "Bad Request" case If you are run the S3 testsuite against a reverse proxy (eg haproxy) rather than RGW directly, some of the tests will return errors from the proxy, rather than haproxy itself. Some proxies differ from RGW in the exact case of 'Bad Request', so do the match in a case-insensitive manner. Haproxy for example returns 'Bad request'. This removes the need for some of the prior fails_on_dho test tags, as the failure was due to haproxy. Signed-off-by: Robin H. Johnson --- s3tests/functional/test_headers.py | 38 ++++++++++++++---------------- s3tests/functional/test_s3.py | 16 ++++++------- 2 files changed, 26 insertions(+), 28 deletions(-) diff --git a/s3tests/functional/test_headers.py b/s3tests/functional/test_headers.py index c361d11..0b410a2 100644 --- a/s3tests/functional/test_headers.py +++ b/s3tests/functional/test_headers.py @@ -185,7 +185,7 @@ def test_object_create_bad_md5_invalid_short(): e = assert_raises(boto.exception.S3ResponseError, key.set_contents_from_string, 'bar') eq(e.status, 400) - eq(e.reason, 'Bad Request') + eq(e.reason.lower(), 'bad request') # some proxies vary the case eq(e.error_code, 'InvalidDigest') @tag('auth_common') @@ -199,7 +199,7 @@ def test_object_create_bad_md5_bad(): e = assert_raises(boto.exception.S3ResponseError, key.set_contents_from_string, 'bar') eq(e.status, 400) - eq(e.reason, 'Bad Request') + eq(e.reason.lower(), 'bad request') # some proxies vary the case eq(e.error_code, 'BadDigest') @tag('auth_common') @@ -213,7 +213,7 @@ def test_object_create_bad_md5_empty(): e = assert_raises(boto.exception.S3ResponseError, key.set_contents_from_string, 'bar') eq(e.status, 400) - eq(e.reason, 'Bad Request') + eq(e.reason.lower(), 'bad request') # some proxies vary the case eq(e.error_code, 'InvalidDigest') @@ -306,7 +306,7 @@ def test_object_create_bad_contentlength_empty(): e = assert_raises(boto.exception.S3ResponseError, key.set_contents_from_string, 'bar') eq(e.status, 400) - eq(e.reason, 'Bad Request') + eq(e.reason.lower(), 'bad request') # some proxies vary the case eq(e.error_code, None) @@ -322,7 +322,7 @@ def test_object_create_bad_contentlength_negative(): e = assert_raises(boto.exception.S3ResponseError, key.set_contents_from_string, 'bar') eq(e.status, 400) - eq(e.reason, 'Bad Request') + eq(e.reason.lower(), 'bad request') # some proxies vary the case @tag('auth_common') @@ -352,7 +352,7 @@ def test_object_create_bad_contentlength_unreadable(): e = assert_raises(boto.exception.S3ResponseError, key.set_contents_from_string, 'bar') eq(e.status, 400) - eq(e.reason, 'Bad Request') + eq(e.reason.lower(), 'bad request') # some proxies vary the case eq(e.error_code, None) @@ -376,7 +376,7 @@ def test_object_create_bad_contentlength_mismatch_above(): e = assert_raises(boto.exception.S3ResponseError, key.set_contents_from_string, content) eq(e.status, 400) - eq(e.reason, 'Bad Request') + eq(e.reason.lower(), 'bad request') # some proxies vary the case eq(e.error_code, 'RequestTimeout') @@ -584,7 +584,7 @@ def test_bucket_create_bad_contentlength_empty(): _add_custom_headers({'Content-Length': ''}) e = assert_raises(boto.exception.S3ResponseError, get_new_bucket, conn) eq(e.status, 400) - eq(e.reason, 'Bad Request') + eq(e.reason.lower(), 'bad request') # some proxies vary the case @tag('auth_common') @@ -598,7 +598,7 @@ def test_bucket_create_bad_contentlength_negative(): _add_custom_headers({'Content-Length': -1}) e = assert_raises(boto.exception.S3ResponseError, get_new_bucket) eq(e.status, 400) - eq(e.reason, 'Bad Request') + eq(e.reason.lower(), 'bad request') # some proxies vary the case @tag('auth_common') @@ -623,7 +623,7 @@ def test_bucket_create_bad_contentlength_unreadable(): _add_custom_headers({'Content-Length': '\x07'}) e = assert_raises(boto.exception.S3ResponseError, get_new_bucket) eq(e.status, 400) - eq(e.reason, 'Bad Request') + eq(e.reason.lower(), 'bad request') # some proxies vary the case eq(e.error_code, None) @@ -685,7 +685,7 @@ def test_object_create_bad_md5_invalid_garbage_aws2(): key = _setup_bad_object({'Content-MD5':'AWS HAHAHA'}) e = assert_raises(boto.exception.S3ResponseError, key.set_contents_from_string, 'bar') eq(e.status, 400) - eq(e.reason, 'Bad Request') + eq(e.reason.lower(), 'bad request') # some proxies vary the case eq(e.error_code, 'InvalidDigest') @@ -701,8 +701,7 @@ def test_object_create_bad_contentlength_mismatch_below_aws2(): key = _setup_bad_object({'Content-Length': length}) e = assert_raises(boto.exception.S3ResponseError, key.set_contents_from_string, content) eq(e.status, 400) - # dho is 'Bad request', which doesn't match the http response code - eq(e.reason, 'Bad Request') + eq(e.reason.lower(), 'bad request') # some proxies vary the case eq(e.error_code, 'BadDigest') @@ -730,7 +729,7 @@ def test_object_create_bad_authorization_invalid_aws2(): key = _setup_bad_object({'Authorization': 'AWS HAHAHA'}) e = assert_raises(boto.exception.S3ResponseError, key.set_contents_from_string, 'bar') eq(e.status, 400) - eq(e.reason, 'Bad Request') + eq(e.reason.lower(), 'bad request') # some proxies vary the case eq(e.error_code, 'InvalidArgument') @@ -890,7 +889,7 @@ def test_bucket_create_bad_authorization_invalid_aws2(): _add_custom_headers({'Authorization': 'AWS HAHAHA'}) e = assert_raises(boto.exception.S3ResponseError, get_new_bucket) eq(e.status, 400) - eq(e.reason, 'Bad Request') + eq(e.reason.lower(), 'bad request') # some proxies vary the case eq(e.error_code, 'InvalidArgument') @@ -1044,7 +1043,7 @@ def test_object_create_bad_md5_invalid_garbage_aws4(): e = assert_raises(boto.exception.S3ResponseError, key.set_contents_from_string, 'bar') eq(e.status, 400) - eq(e.reason, 'Bad Request') + eq(e.reason.lower(), 'bad request') # some proxies vary the case eq(e.error_code, 'InvalidDigest') @@ -1062,8 +1061,7 @@ def test_object_create_bad_contentlength_mismatch_below_aws4(): e = assert_raises(boto.exception.S3ResponseError, key.set_contents_from_string, content) eq(e.status, 400) - # dho is 'Bad request', which doesn't match the http response code - eq(e.reason, 'Bad Request') + eq(e.reason.lower(), 'bad request') # some proxies vary the case eq(e.error_code, 'XAmzContentSHA256Mismatch') @@ -1095,7 +1093,7 @@ def test_object_create_bad_authorization_invalid_aws4(): e = assert_raises(boto.exception.S3ResponseError, key.set_contents_from_string, 'bar') eq(e.status, 400) - eq(e.reason, 'Bad Request') + eq(e.reason.lower(), 'bad request') # some proxies vary the case assert e.error_code in ('AuthorizationHeaderMalformed', 'InvalidArgument') @@ -1419,7 +1417,7 @@ def test_bucket_create_bad_authorization_invalid_aws4(): e = assert_raises(boto.exception.S3ResponseError, get_new_bucket) eq(e.status, 400) - eq(e.reason, 'Bad Request') + eq(e.reason.lower(), 'bad request') # some proxies vary the case eq(e.error_code, 'InvalidArgument') diff --git a/s3tests/functional/test_s3.py b/s3tests/functional/test_s3.py index 0040e43..3170918 100644 --- a/s3tests/functional/test_s3.py +++ b/s3tests/functional/test_s3.py @@ -631,7 +631,7 @@ def test_bucket_list_maxkeys_invalid(): e = assert_raises(boto.exception.S3ResponseError, bucket.get_all_keys, max_keys='blah') eq(e.status, 400) - eq(e.reason, 'Bad Request') + eq(e.reason.lower(), 'bad request') # some proxies vary the case eq(e.error_code, 'InvalidArgument') @@ -645,7 +645,7 @@ def test_bucket_list_maxkeys_unreadable(): e = assert_raises(boto.exception.S3ResponseError, bucket.get_all_keys, max_keys='\x0a') eq(e.status, 400) - eq(e.reason, 'Bad Request') + eq(e.reason.lower(), 'bad request') # some proxies vary the case # Weird because you can clearly see an InvalidArgument error code. What's # also funny is the Amazon tells us that it's not an interger or within an # integer range. Is 'blah' in the integer range? @@ -2774,7 +2774,7 @@ def check_bad_bucket_name(name): """ e = assert_raises(boto.exception.S3ResponseError, get_new_bucket, targets.main.default, name) eq(e.status, 400) - eq(e.reason, 'Bad Request') + eq(e.reason.lower(), 'bad request') # some proxies vary the case eq(e.error_code, 'InvalidBucketName') @@ -3934,7 +3934,7 @@ def test_bucket_acl_grant_nonexist_user(): print policy.to_xml() e = assert_raises(boto.exception.S3ResponseError, bucket.set_acl, policy) eq(e.status, 400) - eq(e.reason, 'Bad Request') + eq(e.reason.lower(), 'bad request') # some proxies vary the case eq(e.error_code, 'InvalidArgument') @@ -4160,7 +4160,7 @@ def test_bucket_acl_grant_email_notexist(): policy.acl.add_email_grant('FULL_CONTROL', NONEXISTENT_EMAIL) e = assert_raises(boto.exception.S3ResponseError, bucket.set_acl, policy) eq(e.status, 400) - eq(e.reason, 'Bad Request') + eq(e.reason.lower(), 'bad request') # some proxies vary the case eq(e.error_code, 'UnresolvableGrantByEmailAddress') @@ -4608,7 +4608,7 @@ def test_object_copy_to_itself(): key.set_contents_from_string('foo') e = assert_raises(boto.exception.S3ResponseError, key.copy, bucket, 'foo123bar') eq(e.status, 400) - eq(e.reason, 'Bad Request') + eq(e.reason.lower(), 'bad request') # some proxies vary the case eq(e.error_code, 'InvalidRequest') @attr(resource='object') @@ -5125,7 +5125,7 @@ def test_multipart_upload_missing_part(): xml = xml.replace('1', '9999') e = assert_raises(boto.exception.S3ResponseError, bucket.complete_multipart_upload, key_name, mp.id, xml) eq(e.status, 400) - eq(e.reason, 'Bad Request') + eq(e.reason.lower(), 'bad request') # some proxies vary the case eq(e.error_code, 'InvalidPart') @attr(resource='object') @@ -5140,7 +5140,7 @@ def test_multipart_upload_incorrect_etag(): xml = xml.replace('"93b885adfe0da089cdf634904fd59f71"', '"ffffffffffffffffffffffffffffffff"') e = assert_raises(boto.exception.S3ResponseError, bucket.complete_multipart_upload, key_name, mp.id, xml) eq(e.status, 400) - eq(e.reason, 'Bad Request') + eq(e.reason.lower(), 'bad request') # some proxies vary the case eq(e.error_code, 'InvalidPart') def _simple_http_req_100_cont(host, port, is_secure, method, resource):