From 085277338fd8a50f0707d21ab0ff568758039da6 Mon Sep 17 00:00:00 2001 From: Ray Lv Date: Mon, 15 Dec 2014 16:47:34 +0800 Subject: [PATCH 1/2] s3tests: add regression test for bug #10311 - rgw: Object is deleted automatically if conditional PUT returns 412 Test for bug #10311 Signed-off-by: Ray Lv --- s3tests/functional/test_s3.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/s3tests/functional/test_s3.py b/s3tests/functional/test_s3.py index 3c8ff22..acd914f 100644 --- a/s3tests/functional/test_s3.py +++ b/s3tests/functional/test_s3.py @@ -2086,6 +2086,9 @@ def test_put_object_ifmatch_failed(): eq(e.reason, 'Precondition Failed') eq(e.error_code, 'PreconditionFailed') + got_old_data = key.get_contents_as_string() + eq(got_old_data, 'bar') + @attr(resource='object') @attr(method='put') @@ -2117,6 +2120,10 @@ def test_put_object_ifmatch_nonexisted_failed(): eq(e.reason, 'Precondition Failed') eq(e.error_code, 'PreconditionFailed') + e = assert_raises(boto.exception.S3ResponseError, key.get_contents_as_string) + eq(e.status, 404) + eq(e.reason, 'Not Found') + eq(e.error_code, 'NoSuchKey') @attr(resource='object') @attr(method='put') @@ -2153,6 +2160,8 @@ def test_put_object_ifnonmatch_failed(): eq(e.reason, 'Precondition Failed') eq(e.error_code, 'PreconditionFailed') + got_old_data = key.get_contents_as_string() + eq(got_old_data, 'bar') @attr(resource='object') @attr(method='put') @@ -2185,6 +2194,9 @@ def test_put_object_ifnonmatch_overwrite_existed_failed(): eq(e.reason, 'Precondition Failed') eq(e.error_code, 'PreconditionFailed') + got_old_data = key.get_contents_as_string() + eq(got_old_data, 'bar') + def _setup_request(bucket_acl=None, object_acl=None): """ From 76e8bed4bd48f050f1de6dc38da072ecd38d3286 Mon Sep 17 00:00:00 2001 From: Yehuda Sadeh Date: Tue, 13 Jan 2015 16:46:33 -0800 Subject: [PATCH 2/2] s3tests: send raw http requests to test redirects Since we fixed the rgw redirect code, it turns out that boto actually follows on them. We just want to check if redirect is sent. Signed-off-by: Yehuda Sadeh --- requirements.txt | 1 + s3tests/functional/test_s3.py | 33 ++++++++++++++++++++++++--------- 2 files changed, 25 insertions(+), 9 deletions(-) diff --git a/requirements.txt b/requirements.txt index 81e93e9..9c294dc 100644 --- a/requirements.txt +++ b/requirements.txt @@ -8,3 +8,4 @@ isodate >=0.4.4 requests ==0.14.0 pytz >=2011k ordereddict +httplib2 diff --git a/s3tests/functional/test_s3.py b/s3tests/functional/test_s3.py index 0d7eff3..ab02f1d 100644 --- a/s3tests/functional/test_s3.py +++ b/s3tests/functional/test_s3.py @@ -20,6 +20,7 @@ import hmac import sha import pytz import json +import httplib2 import xml.etree.ElementTree as ET @@ -5029,6 +5030,21 @@ def check_can_test_multiregion(): if not targets.main.master or len(targets.main.secondaries) == 0: raise SkipTest +def create_presigned_url(conn, method, bucket_name, key_name, expiration): + return conn.generate_url(expires_in=expiration, + method=method, + bucket=bucket_name, + key=key_name, + query_auth=True, + ) + +def send_raw_http_request(conn, method, bucket_name, key_name, follow_redirects = False): + url = create_presigned_url(conn, method, bucket_name, key_name, 3600) + print url + h = httplib2.Http() + h.follow_redirects = follow_redirects + return h.request(url, method) + @attr(resource='bucket') @attr(method='get') @attr(operation='create on one region, access in another') @@ -5043,12 +5059,11 @@ def test_region_bucket_create_secondary_access_remove_master(): conn = r.connection bucket = get_new_bucket(r) - e = assert_raises(boto.exception.S3ResponseError, master_conn.get_bucket, bucket.name) - eq(e.status, 301) - - e = assert_raises(boto.exception.S3ResponseError, master_conn.delete_bucket, bucket.name) - eq(e.status, 301) + r, content = send_raw_http_request(master_conn, 'GET', bucket.name, '', follow_redirects = False) + eq(r.status, 301) + r, content = send_raw_http_request(master_conn, 'DELETE', bucket.name, '', follow_redirects = False) + eq(r.status, 301) conn.delete_bucket(bucket) @@ -5069,11 +5084,11 @@ def test_region_bucket_create_master_access_remove_secondary(): region_sync_meta(targets.main, master) - e = assert_raises(boto.exception.S3ResponseError, conn.get_bucket, bucket.name) - eq(e.status, 301) + r, content = send_raw_http_request(conn, 'GET', bucket.name, '', follow_redirects = False) + eq(r.status, 301) - e = assert_raises(boto.exception.S3ResponseError, conn.delete_bucket, bucket.name) - eq(e.status, 301) + r, content = send_raw_http_request(conn, 'DELETE', bucket.name, '', follow_redirects = False) + eq(r.status, 301) master_conn.delete_bucket(bucket) region_sync_meta(targets.main, master)