def test_put_object_copy_error(self): obj = 'object' self.conn.make_request('PUT', self.bucket, obj) dst_bucket = 'dst-bucket' self.conn.make_request('PUT', dst_bucket) dst_obj = 'dst_object' headers = {'x-amz-copy-source': '/%s/%s' % (self.bucket, obj)} auth_error_conn = Connection(aws_secret_key='invalid') status, headers, body = \ auth_error_conn.make_request('PUT', dst_bucket, dst_obj, headers) self.assertEqual(get_error_code(body), 'SignatureDoesNotMatch') self.assertEqual(headers['content-type'], 'application/xml') # /src/nothing -> /dst/dst headers = {'X-Amz-Copy-Source': '/%s/%s' % (self.bucket, 'nothing')} status, headers, body = \ self.conn.make_request('PUT', dst_bucket, dst_obj, headers) self.assertEqual(get_error_code(body), 'NoSuchKey') self.assertEqual(headers['content-type'], 'application/xml') # /nothing/src -> /dst/dst headers = {'X-Amz-Copy-Source': '/%s/%s' % ('nothing', obj)} status, headers, body = \ self.conn.make_request('PUT', dst_bucket, dst_obj, headers) # TODO: source bucket is not check. # self.assertEqual(get_error_code(body), 'NoSuchBucket') # /src/src -> /nothing/dst headers = {'X-Amz-Copy-Source': '/%s/%s' % (self.bucket, obj)} status, headers, body = \ self.conn.make_request('PUT', 'nothing', dst_obj, headers) self.assertEqual(get_error_code(body), 'NoSuchBucket') self.assertEqual(headers['content-type'], 'application/xml')
def test_put_object_copy_source_params(self): obj = 'object' src_headers = {'X-Amz-Meta-Test': 'src'} src_body = 'some content' dst_bucket = 'dst-bucket' dst_obj = 'dst_object' self.conn.make_request('PUT', self.bucket, obj, src_headers, src_body) self.conn.make_request('PUT', dst_bucket) headers = {'X-Amz-Copy-Source': '/%s/%s?nonsense' % ( self.bucket, obj)} status, headers, body = \ self.conn.make_request('PUT', dst_bucket, dst_obj, headers) self.assertEqual(status, 400) self.assertEqual(get_error_code(body), 'InvalidArgument') headers = {'X-Amz-Copy-Source': '/%s/%s?versionId=null&nonsense' % ( self.bucket, obj)} status, headers, body = \ self.conn.make_request('PUT', dst_bucket, dst_obj, headers) self.assertEqual(status, 400) self.assertEqual(get_error_code(body), 'InvalidArgument') headers = {'X-Amz-Copy-Source': '/%s/%s?versionId=null' % ( self.bucket, obj)} status, headers, body = \ self.conn.make_request('PUT', dst_bucket, dst_obj, headers) self.assertEqual(status, 200) self.assertCommonResponseHeaders(headers) status, headers, body = \ self.conn.make_request('GET', dst_bucket, dst_obj) self.assertEqual(status, 200) self.assertEqual(headers['x-amz-meta-test'], 'src') self.assertEqual(body, src_body)
def test_upload_part_error(self): bucket = 'bucket' self.conn.make_request('PUT', bucket) query = 'uploads' key = 'obj' status, headers, body = \ self.conn.make_request('POST', bucket, key, query=query) elem = fromstring(body, 'InitiateMultipartUploadResult') upload_id = elem.find('UploadId').text query = 'partNumber=%s&uploadId=%s' % (1, upload_id) auth_error_conn = Connection(aws_secret_key='invalid') status, headers, body = \ auth_error_conn.make_request('PUT', bucket, key, query=query) self.assertEqual(get_error_code(body), 'SignatureDoesNotMatch') status, headers, body = \ self.conn.make_request('PUT', 'nothing', key, query=query) self.assertEqual(get_error_code(body), 'NoSuchBucket') query = 'partNumber=%s&uploadId=%s' % (1, 'nothing') status, headers, body = \ self.conn.make_request('PUT', bucket, key, query=query) self.assertEqual(get_error_code(body), 'NoSuchUpload') query = 'partNumber=%s&uploadId=%s' % (0, upload_id) status, headers, body = \ self.conn.make_request('PUT', bucket, key, query=query) self.assertEqual(get_error_code(body), 'InvalidArgument') err_msg = 'Part number must be an integer between 1 and' self.assertTrue(err_msg in get_error_msg(body))
def test_abort_multi_upload_error(self): bucket = 'bucket' self.conn.make_request('PUT', bucket) key = 'obj' query = 'uploads' status, headers, body = \ self.conn.make_request('POST', bucket, key, query=query) elem = fromstring(body, 'InitiateMultipartUploadResult') upload_id = elem.find('UploadId').text self._upload_part(bucket, key, upload_id) query = 'uploadId=%s' % upload_id auth_error_conn = Connection(aws_secret_key='invalid') status, headers, body = \ auth_error_conn.make_request('DELETE', bucket, key, query=query) self.assertEqual(get_error_code(body), 'SignatureDoesNotMatch') status, headers, body = \ self.conn.make_request('DELETE', 'nothing', key, query=query) self.assertEqual(get_error_code(body), 'NoSuchBucket') status, headers, body = \ self.conn.make_request('DELETE', bucket, 'nothing', query=query) self.assertEqual(get_error_code(body), 'NoSuchUpload') query = 'uploadId=%s' % 'nothing' status, headers, body = \ self.conn.make_request('DELETE', bucket, key, query=query) self.assertEqual(get_error_code(body), 'NoSuchUpload')
def test_abort_multi_upload_error(self): bucket = 'bucket' self.conn.make_request('PUT', bucket) key = 'obj' query = 'uploads' status, headers, body = \ self.conn.make_request('POST', bucket, key, query=query) elem = fromstring(body, 'InitiateMultipartUploadResult') upload_id = elem.find('UploadId').text self._upload_part(bucket, key, upload_id) query = 'uploadId=%s' % upload_id auth_error_conn = Connection(aws_secret_key='invalid') status, headers, body = \ auth_error_conn.make_request('DELETE', bucket, key, query=query) self.assertEquals(get_error_code(body), 'SignatureDoesNotMatch') status, headers, body = \ self.conn.make_request('DELETE', 'nothing', key, query=query) self.assertEquals(get_error_code(body), 'NoSuchBucket') query = 'uploadId=%s' % 'nothing' status, headers, body = \ self.conn.make_request('DELETE', bucket, key, query=query) self.assertEquals(get_error_code(body), 'NoSuchUpload')
def test_upload_part_error(self): bucket = 'bucket' self.conn.make_request('PUT', bucket) query = 'uploads' key = 'obj' status, headers, body = \ self.conn.make_request('POST', bucket, key, query=query) elem = fromstring(body, 'InitiateMultipartUploadResult') upload_id = elem.find('UploadId').text query = 'partNumber=%s&uploadId=%s' % (1, upload_id) auth_error_conn = Connection(aws_secret_key='invalid') status, headers, body = \ auth_error_conn.make_request('PUT', bucket, key, query=query) self.assertEquals(get_error_code(body), 'SignatureDoesNotMatch') status, headers, body = \ self.conn.make_request('PUT', 'nothing', key, query=query) self.assertEquals(get_error_code(body), 'NoSuchBucket') query = 'partNumber=%s&uploadId=%s' % (1, 'nothing') status, headers, body = \ self.conn.make_request('PUT', bucket, key, query=query) self.assertEquals(get_error_code(body), 'NoSuchUpload') query = 'partNumber=%s&uploadId=%s' % (0, upload_id) status, headers, body = \ self.conn.make_request('PUT', bucket, key, query=query) self.assertEquals(get_error_code(body), 'InvalidArgument') err_msg = 'Part number must be an integer between 1 and' self.assertTrue(err_msg in get_error_msg(body))
def test_put_object_copy_error(self): obj = 'object' self.conn.make_request('PUT', self.bucket, obj) dst_bucket = 'dst-bucket' self.conn.make_request('PUT', dst_bucket) dst_obj = 'dst_object' headers = {'x-amz-copy-source': '/%s/%s' % (self.bucket, obj)} auth_error_conn = Connection(aws_secret_key='invalid') status, headers, body = \ auth_error_conn.make_request('PUT', dst_bucket, dst_obj, headers) self.assertEquals(get_error_code(body), 'SignatureDoesNotMatch') # /src/nothing -> /dst/dst headers = {'X-Amz-Copy-Source': '/%s/%s' % (self.bucket, 'nothing')} status, headers, body = \ self.conn.make_request('PUT', dst_bucket, dst_obj, headers) self.assertEquals(get_error_code(body), 'NoSuchKey') # /nothing/src -> /dst/dst headers = {'X-Amz-Copy-Source': '/%s/%s' % ('nothing', obj)} status, headers, body = \ self.conn.make_request('PUT', dst_bucket, dst_obj, headers) # TODO: source bucket is not check. # self.assertEquals(get_error_code(body), 'NoSuchBucket') # /src/src -> /nothing/dst headers = {'X-Amz-Copy-Source': '/%s/%s' % (self.bucket, obj)} status, headers, body = \ self.conn.make_request('PUT', 'nothing', dst_obj, headers) self.assertEquals(get_error_code(body), 'NoSuchBucket')
def test_put_object_error(self): auth_error_conn = Connection(aws_secret_key='invalid') status, headers, body = \ auth_error_conn.make_request('PUT', self.bucket, 'object') self.assertEquals(get_error_code(body), 'SignatureDoesNotMatch') status, headers, body = \ self.conn.make_request('PUT', 'bucket2', 'object') self.assertEquals(get_error_code(body), 'NoSuchBucket')
def test_bucket_invalid_method_error(self): # non existed verb in the controller status, headers, body = \ self.conn.make_request('GETPUT', 'bucket') self.assertEqual(get_error_code(body), 'MethodNotAllowed') # the method exists in the controller but deny as MethodNotAllowed status, headers, body = \ self.conn.make_request('_delete_segments_bucket', 'bucket') self.assertEqual(get_error_code(body), 'MethodNotAllowed')
def test_delete_bucket_error(self): status, headers, body = \ self.conn.make_request('DELETE', 'bucket+invalid') self.assertEquals(get_error_code(body), 'InvalidBucketName') auth_error_conn = Connection(aws_secret_key='invalid') status, headers, body = \ auth_error_conn.make_request('DELETE', 'bucket') self.assertEquals(get_error_code(body), 'SignatureDoesNotMatch') status, headers, body = self.conn.make_request('DELETE', 'bucket') self.assertEquals(get_error_code(body), 'NoSuchBucket')
def test_put_bucket_error(self): status, headers, body = \ self.conn.make_request('PUT', 'bucket+invalid') self.assertEquals(get_error_code(body), 'InvalidBucketName') auth_error_conn = Connection(aws_secret_key='invalid') status, headers, body = auth_error_conn.make_request('PUT', 'bucket') self.assertEquals(get_error_code(body), 'SignatureDoesNotMatch') self.conn.make_request('PUT', 'bucket') status, headers, body = self.conn.make_request('PUT', 'bucket') self.assertEquals(get_error_code(body), 'BucketAlreadyExists')
def test_put_bucket_error(self): status, headers, body = \ self.conn.make_request('PUT', 'bucket+invalid') self.assertEqual(get_error_code(body), 'InvalidBucketName') auth_error_conn = Connection(aws_secret_key='invalid') status, headers, body = auth_error_conn.make_request('PUT', 'bucket') self.assertEqual(get_error_code(body), 'SignatureDoesNotMatch') self.conn.make_request('PUT', 'bucket') status, headers, body = self.conn.make_request('PUT', 'bucket') self.assertEqual(get_error_code(body), 'BucketAlreadyExists')
def test_delete_bucket_error(self): status, headers, body = \ self.conn.make_request('DELETE', 'bucket+invalid') self.assertEqual(get_error_code(body), 'InvalidBucketName') auth_error_conn = Connection(aws_secret_key='invalid') status, headers, body = \ auth_error_conn.make_request('DELETE', 'bucket') self.assertEqual(get_error_code(body), 'SignatureDoesNotMatch') status, headers, body = self.conn.make_request('DELETE', 'bucket') self.assertEqual(get_error_code(body), 'NoSuchBucket')
def test_list_multi_uploads_error(self): bucket = 'bucket' self.conn.make_request('PUT', bucket) query = 'uploads' auth_error_conn = Connection(aws_secret_key='invalid') status, headers, body = \ auth_error_conn.make_request('GET', bucket, query=query) self.assertEqual(get_error_code(body), 'SignatureDoesNotMatch') status, headers, body = \ self.conn.make_request('GET', 'nothing', query=query) self.assertEqual(get_error_code(body), 'NoSuchBucket')
def test_get_bucket_error(self): self.conn.make_request('PUT', 'bucket') status, headers, body = \ self.conn.make_request('GET', 'bucket+invalid') self.assertEquals(get_error_code(body), 'InvalidBucketName') auth_error_conn = Connection(aws_secret_key='invalid') status, headers, body = auth_error_conn.make_request('GET', 'bucket') self.assertEquals(get_error_code(body), 'SignatureDoesNotMatch') status, headers, body = self.conn.make_request('GET', 'nothing') self.assertEquals(get_error_code(body), 'NoSuchBucket')
def test_get_bucket_error(self): self.conn.make_request('PUT', 'bucket') status, headers, body = \ self.conn.make_request('GET', 'bucket+invalid') self.assertEqual(get_error_code(body), 'InvalidBucketName') auth_error_conn = Connection(aws_secret_key='invalid') status, headers, body = auth_error_conn.make_request('GET', 'bucket') self.assertEqual(get_error_code(body), 'SignatureDoesNotMatch') status, headers, body = self.conn.make_request('GET', 'nothing') self.assertEqual(get_error_code(body), 'NoSuchBucket')
def test_get_bucket_acl_error(self): aws_error_conn = Connection(aws_secret_key='invalid') status, headers, body = \ aws_error_conn.make_request('GET', self.bucket, query='acl') self.assertEquals(get_error_code(body), 'SignatureDoesNotMatch') status, headers, body = \ self.conn.make_request('GET', 'nothing', query='acl') self.assertEquals(get_error_code(body), 'NoSuchBucket') status, headers, body = \ self.conn2.make_request('GET', self.bucket, query='acl') self.assertEquals(get_error_code(body), 'AccessDenied')
def test_list_multi_uploads_error(self): bucket = 'bucket' self.conn.make_request('PUT', bucket) query = 'uploads' auth_error_conn = Connection(aws_secret_key='invalid') status, headers, body = \ auth_error_conn.make_request('GET', bucket, query=query) self.assertEquals(get_error_code(body), 'SignatureDoesNotMatch') status, headers, body = \ self.conn.make_request('GET', 'nothing', query=query) self.assertEquals(get_error_code(body), 'NoSuchBucket')
def test_get_bucket_acl_error(self): aws_error_conn = Connection(aws_secret_key='invalid') status, headers, body = \ aws_error_conn.make_request('GET', self.bucket, query='acl') self.assertEqual(get_error_code(body), 'SignatureDoesNotMatch') status, headers, body = \ self.conn.make_request('GET', 'nothing', query='acl') self.assertEqual(get_error_code(body), 'NoSuchBucket') status, headers, body = \ self.conn2.make_request('GET', self.bucket, query='acl') self.assertEqual(get_error_code(body), 'AccessDenied')
def test_delete_object_error(self): obj = 'object' self.conn.make_request('PUT', self.bucket, obj) auth_error_conn = Connection(aws_secret_key='invalid') status, headers, body = \ auth_error_conn.make_request('DELETE', self.bucket, obj) self.assertEqual(get_error_code(body), 'SignatureDoesNotMatch') self.assertEqual(headers['content-type'], 'application/xml') status, headers, body = \ self.conn.make_request('DELETE', 'invalid', obj) self.assertEqual(get_error_code(body), 'NoSuchBucket') self.assertEqual(headers['content-type'], 'application/xml')
def test_delete_object_error(self): obj = 'object' self.conn.make_request('PUT', self.bucket, obj) auth_error_conn = Connection(aws_secret_key='invalid') status, headers, body = \ auth_error_conn.make_request('DELETE', self.bucket, obj) self.assertEquals(get_error_code(body), 'SignatureDoesNotMatch') status, headers, body = \ self.conn.make_request('DELETE', self.bucket, 'invalid') self.assertEquals(get_error_code(body), 'NoSuchKey') status, headers, body = \ self.conn.make_request('DELETE', 'invalid', obj) self.assertEquals(get_error_code(body), 'NoSuchBucket')
def test_upload_part_copy_error(self): src_bucket = 'src' src_obj = 'src' self.conn.make_request('PUT', src_bucket) self.conn.make_request('PUT', src_bucket, src_obj) src_path = '%s/%s' % (src_bucket, src_obj) bucket = 'bucket' self.conn.make_request('PUT', bucket) key = 'obj' query = 'uploads' status, headers, body = \ self.conn.make_request('POST', bucket, key, query=query) elem = fromstring(body, 'InitiateMultipartUploadResult') upload_id = elem.find('UploadId').text query = 'partNumber=%s&uploadId=%s' % (1, upload_id) auth_error_conn = Connection(aws_secret_key='invalid') status, headers, body = \ auth_error_conn.make_request('PUT', bucket, key, headers={ 'X-Amz-Copy-Source': src_path }, query=query) self.assertEquals(get_error_code(body), 'SignatureDoesNotMatch') status, headers, body = \ self.conn.make_request('PUT', 'nothing', key, headers={'X-Amz-Copy-Source': src_path}, query=query) self.assertEquals(get_error_code(body), 'NoSuchBucket') query = 'partNumber=%s&uploadId=%s' % (1, 'nothing') status, headers, body = \ self.conn.make_request('PUT', bucket, key, headers={'X-Amz-Copy-Source': src_path}, query=query) self.assertEquals(get_error_code(body), 'NoSuchUpload') src_path = '%s/%s' % (src_bucket, 'nothing') query = 'partNumber=%s&uploadId=%s' % (1, upload_id) status, headers, body = \ self.conn.make_request('PUT', bucket, key, headers={'X-Amz-Copy-Source': src_path}, query=query) self.assertEquals(get_error_code(body), 'NoSuchKey')
def test_service_error_no_date_header(self): # Without x-amz-date/Date header, that makes 403 forbidden status, headers, body = self.conn.make_request( 'GET', headers={'Date': '', 'x-amz-date': ''}) self.assertEqual(status, 403) self.assertEqual(get_error_code(body), 'AccessDenied') self.assertIn('AWS authentication requires a valid Date ' 'or x-amz-date header', body)
def test_upload_part_copy_error(self): src_bucket = 'src' src_obj = 'src' self.conn.make_request('PUT', src_bucket) self.conn.make_request('PUT', src_bucket, src_obj) src_path = '%s/%s' % (src_bucket, src_obj) bucket = 'bucket' self.conn.make_request('PUT', bucket) key = 'obj' query = 'uploads' status, headers, body = \ self.conn.make_request('POST', bucket, key, query=query) elem = fromstring(body, 'InitiateMultipartUploadResult') upload_id = elem.find('UploadId').text query = 'partNumber=%s&uploadId=%s' % (1, upload_id) auth_error_conn = Connection(aws_secret_key='invalid') status, headers, body = \ auth_error_conn.make_request('PUT', bucket, key, headers={ 'X-Amz-Copy-Source': src_path }, query=query) self.assertEqual(get_error_code(body), 'SignatureDoesNotMatch') status, headers, body = \ self.conn.make_request('PUT', 'nothing', key, headers={'X-Amz-Copy-Source': src_path}, query=query) self.assertEqual(get_error_code(body), 'NoSuchBucket') query = 'partNumber=%s&uploadId=%s' % (1, 'nothing') status, headers, body = \ self.conn.make_request('PUT', bucket, key, headers={'X-Amz-Copy-Source': src_path}, query=query) self.assertEqual(get_error_code(body), 'NoSuchUpload') src_path = '%s/%s' % (src_bucket, 'nothing') query = 'partNumber=%s&uploadId=%s' % (1, upload_id) status, headers, body = \ self.conn.make_request('PUT', bucket, key, headers={'X-Amz-Copy-Source': src_path}, query=query) self.assertEqual(get_error_code(body), 'NoSuchKey')
def test_put_bucket_acl_error(self): req_headers = {'x-amz-acl': 'public-read'} aws_error_conn = Connection(aws_secret_key='invalid') status, headers, body = \ aws_error_conn.make_request('PUT', self.bucket, headers=req_headers, query='acl') self.assertEqual(get_error_code(body), 'SignatureDoesNotMatch') status, headers, body = \ self.conn.make_request('PUT', 'nothing', headers=req_headers, query='acl') self.assertEqual(get_error_code(body), 'NoSuchBucket') status, headers, body = \ self.conn2.make_request('PUT', self.bucket, headers=req_headers, query='acl') self.assertEqual(get_error_code(body), 'AccessDenied')
def test_get_object_error(self): obj = 'object' self.conn.make_request('PUT', self.bucket, obj) auth_error_conn = Connection(aws_secret_key='invalid') status, headers, body = \ auth_error_conn.make_request('GET', self.bucket, obj) self.assertEquals(get_error_code(body), 'SignatureDoesNotMatch') status, headers, body = \ self.conn.make_request('GET', self.bucket, 'invalid') self.assertEquals(get_error_code(body), 'NoSuchKey') status, headers, body = self.conn.make_request('GET', 'invalid', obj) # TODO; requires consideration # self.assertEquals(get_error_code(body), 'NoSuchBucket') self.assertEquals(get_error_code(body), 'NoSuchKey')
def test_put_bucket_acl_error(self): req_headers = {'x-amz-acl': 'public-read'} aws_error_conn = Connection(aws_secret_key='invalid') status, headers, body = \ aws_error_conn.make_request('PUT', self.bucket, headers=req_headers, query='acl') self.assertEquals(get_error_code(body), 'SignatureDoesNotMatch') status, headers, body = \ self.conn.make_request('PUT', 'nothing', headers=req_headers, query='acl') self.assertEquals(get_error_code(body), 'NoSuchBucket') status, headers, body = \ self.conn2.make_request('PUT', self.bucket, headers=req_headers, query='acl') self.assertEquals(get_error_code(body), 'AccessDenied')
def test_get_object_error(self): obj = 'object' self.conn.make_request('PUT', self.bucket, obj) auth_error_conn = Connection(aws_secret_key='invalid') status, headers, body = \ auth_error_conn.make_request('GET', self.bucket, obj) self.assertEqual(get_error_code(body), 'SignatureDoesNotMatch') self.assertEqual(headers['content-type'], 'application/xml') status, headers, body = \ self.conn.make_request('GET', self.bucket, 'invalid') self.assertEqual(get_error_code(body), 'NoSuchKey') self.assertEqual(headers['content-type'], 'application/xml') status, headers, body = self.conn.make_request('GET', 'invalid', obj) self.assertEqual(get_error_code(body), 'NoSuchBucket') self.assertEqual(headers['content-type'], 'application/xml')
def test_object(self): bucket = 'test-bucket' obj = 'object' status, _junk, _junk = self.conn.make_request('PUT', bucket) self.assertEqual(status, 200) # HEAD/missing object head_url, headers = self.conn.generate_url_and_headers( 'HEAD', bucket, obj) resp = requests.head(head_url, headers=headers) self.assertEqual(resp.status_code, 404, 'Got %d %s' % (resp.status_code, resp.content)) # Wrong verb resp = requests.get(head_url) self.assertEqual(resp.status_code, 403, 'Got %d %s' % (resp.status_code, resp.content)) self.assertEqual(get_error_code(resp.content), 'SignatureDoesNotMatch') # PUT empty object put_url, headers = self.conn.generate_url_and_headers( 'PUT', bucket, obj) resp = requests.put(put_url, data='', headers=headers) self.assertEqual(resp.status_code, 200, 'Got %d %s' % (resp.status_code, resp.content)) # GET empty object get_url, headers = self.conn.generate_url_and_headers( 'GET', bucket, obj) resp = requests.get(get_url, headers=headers) self.assertEqual(resp.status_code, 200, 'Got %d %s' % (resp.status_code, resp.content)) self.assertEqual(resp.content, '') # PUT over object resp = requests.put(put_url, data='foobar', headers=headers) self.assertEqual(resp.status_code, 200, 'Got %d %s' % (resp.status_code, resp.content)) # GET non-empty object resp = requests.get(get_url, headers=headers) self.assertEqual(resp.status_code, 200, 'Got %d %s' % (resp.status_code, resp.content)) self.assertEqual(resp.content, 'foobar') # DELETE Object delete_url, headers = self.conn.generate_url_and_headers( 'DELETE', bucket, obj) resp = requests.delete(delete_url, headers=headers) self.assertEqual(resp.status_code, 204, 'Got %d %s' % (resp.status_code, resp.content)) # Final cleanup status, _junk, _junk = self.conn.make_request('DELETE', bucket) self.assertEqual(status, 204)
def _test_expiration_limits_v4(self): bucket = 'test-bucket' # Expiration is negative url, headers = self.conn.generate_url_and_headers('GET', bucket, expires_in=-1) resp = requests.get(url, headers=headers) self.assertEqual(resp.status_code, 400, 'Got %d %s' % (resp.status_code, resp.content)) self.assertEqual(get_error_code(resp.content), 'AuthorizationQueryParametersError') self.assertIn('X-Amz-Expires must be non-negative', get_error_msg(resp.content)) # Expiration date is too far in the future for exp in (7 * 24 * 60 * 60 + 1, 2**63 - 1): url, headers = self.conn.generate_url_and_headers('GET', bucket, expires_in=exp) resp = requests.get(url, headers=headers) self.assertEqual(resp.status_code, 400, 'Got %d %s' % (resp.status_code, resp.content)) self.assertEqual(get_error_code(resp.content), 'AuthorizationQueryParametersError') self.assertIn('X-Amz-Expires must be less than 604800 seconds', get_error_msg(resp.content)) # Expiration date is *way* too far in the future, or isn't a number for exp in (2**63, 'foo'): url, headers = self.conn.generate_url_and_headers('GET', bucket, expires_in=2**63) resp = requests.get(url, headers=headers) self.assertEqual(resp.status_code, 400, 'Got %d %s' % (resp.status_code, resp.content)) self.assertEqual(get_error_code(resp.content), 'AuthorizationQueryParametersError') self.assertEqual('X-Amz-Expires should be a number', get_error_msg(resp.content))
def _test_expiration_limits_v2(self): bucket = 'test-bucket' # Expiration date is too far in the future url, headers = self.conn.generate_url_and_headers( 'GET', bucket, expires_in=2 ** 32) resp = requests.get(url, headers=headers) self.assertEqual(resp.status_code, 403, 'Got %d %s' % (resp.status_code, resp.content)) self.assertEqual(get_error_code(resp.content), 'AccessDenied') self.assertIn('Invalid date (should be seconds since epoch)', get_error_msg(resp.content))
def _test_expiration_limits_v2(self): bucket = 'test-bucket' # Expiration date is too far in the future url, headers = self.conn.generate_url_and_headers('GET', bucket, expires_in=2**32) resp = requests.get(url, headers=headers) self.assertEqual(resp.status_code, 403, 'Got %d %s' % (resp.status_code, resp.content)) self.assertEqual(get_error_code(resp.content), 'AccessDenied') self.assertIn('Invalid date (should be seconds since epoch)', get_error_msg(resp.content))
def test_versioning_put_error(self): # Root tag is not VersioningConfiguration elem = Element('foo') SubElement(elem, 'Status').text = 'Enabled' xml = tostring(elem) status, headers, body = self.conn.make_request('PUT', 'bucket', body=xml, query='versioning') self.assertEqual(status, 400) self.assertEqual(get_error_code(body), 'MalformedXML') # Status is not "Enabled" or "Suspended" elem = Element('VersioningConfiguration') SubElement(elem, 'Status').text = '...' xml = tostring(elem) status, headers, body = self.conn.make_request('PUT', 'bucket', body=xml, query='versioning') self.assertEqual(status, 400) self.assertEqual(get_error_code(body), 'MalformedXML')
def _test_expiration_limits_v4(self): bucket = 'test-bucket' # Expiration is negative url, headers = self.conn.generate_url_and_headers( 'GET', bucket, expires_in=-1) resp = requests.get(url, headers=headers) self.assertEqual(resp.status_code, 400, 'Got %d %s' % (resp.status_code, resp.content)) self.assertEqual(get_error_code(resp.content), 'AuthorizationQueryParametersError') self.assertIn('X-Amz-Expires must be non-negative', get_error_msg(resp.content)) # Expiration date is too far in the future for exp in (7 * 24 * 60 * 60 + 1, 2 ** 63 - 1): url, headers = self.conn.generate_url_and_headers( 'GET', bucket, expires_in=exp) resp = requests.get(url, headers=headers) self.assertEqual(resp.status_code, 400, 'Got %d %s' % (resp.status_code, resp.content)) self.assertEqual(get_error_code(resp.content), 'AuthorizationQueryParametersError') self.assertIn('X-Amz-Expires must be less than 604800 seconds', get_error_msg(resp.content)) # Expiration date is *way* too far in the future, or isn't a number for exp in (2 ** 63, 'foo'): url, headers = self.conn.generate_url_and_headers( 'GET', bucket, expires_in=2 ** 63) resp = requests.get(url, headers=headers) self.assertEqual(resp.status_code, 400, 'Got %d %s' % (resp.status_code, resp.content)) self.assertEqual(get_error_code(resp.content), 'AuthorizationQueryParametersError') self.assertEqual('X-Amz-Expires should be a number', get_error_msg(resp.content))
def test_put_object_copy_source_params(self): obj = 'object' src_headers = {'X-Amz-Meta-Test': 'src'} src_body = 'some content' dst_bucket = 'dst-bucket' dst_obj = 'dst_object' self.conn.make_request('PUT', self.bucket, obj, src_headers, src_body) self.conn.make_request('PUT', dst_bucket) headers = {'X-Amz-Copy-Source': '/%s/%s?nonsense' % (self.bucket, obj)} status, headers, body = \ self.conn.make_request('PUT', dst_bucket, dst_obj, headers) self.assertEqual(status, 400) self.assertEqual(get_error_code(body), 'InvalidArgument') headers = { 'X-Amz-Copy-Source': '/%s/%s?versionId=null&nonsense' % (self.bucket, obj) } status, headers, body = \ self.conn.make_request('PUT', dst_bucket, dst_obj, headers) self.assertEqual(status, 400) self.assertEqual(get_error_code(body), 'InvalidArgument') headers = { 'X-Amz-Copy-Source': '/%s/%s?versionId=null' % (self.bucket, obj) } status, headers, body = \ self.conn.make_request('PUT', dst_bucket, dst_obj, headers) self.assertEqual(status, 200) self.assertCommonResponseHeaders(headers) status, headers, body = \ self.conn.make_request('GET', dst_bucket, dst_obj) self.assertEqual(status, 200) self.assertEqual(headers['x-amz-meta-test'], 'src') self.assertEqual(body, src_body)
def test_service_error(self): auth_error_conn = Connection(aws_secret_key="invalid") status, headers, body = auth_error_conn.make_request("GET") self.assertEquals(get_error_code(body), "SignatureDoesNotMatch")
def test_complete_upload_min_segment_size(self): bucket = 'bucket' key = 'obj' self.conn.make_request('PUT', bucket) query = 'uploads' status, headers, body = \ self.conn.make_request('POST', bucket, key, query=query) elem = fromstring(body, 'InitiateMultipartUploadResult') upload_id = elem.find('UploadId').text # multi parts with no body etags = [] for i in xrange(1, 3): query = 'partNumber=%s&uploadId=%s' % (i, upload_id) status, headers, body = \ self.conn.make_request('PUT', bucket, key, query=query) etags.append(headers['etag']) xml = self._gen_comp_xml(etags) query = 'uploadId=%s' % upload_id status, headers, body = \ self.conn.make_request('POST', bucket, key, body=xml, query=query) self.assertEqual(get_error_code(body), 'EntityTooSmall') # multi parts with all parts less than min segment size etags = [] for i in xrange(1, 3): query = 'partNumber=%s&uploadId=%s' % (i, upload_id) status, headers, body = \ self.conn.make_request('PUT', bucket, key, query=query, body='AA') etags.append(headers['etag']) xml = self._gen_comp_xml(etags) query = 'uploadId=%s' % upload_id status, headers, body = \ self.conn.make_request('POST', bucket, key, body=xml, query=query) self.assertEqual(get_error_code(body), 'EntityTooSmall') # one part and less than min segment size etags = [] query = 'partNumber=1&uploadId=%s' % upload_id status, headers, body = \ self.conn.make_request('PUT', bucket, key, query=query, body='AA') etags.append(headers['etag']) xml = self._gen_comp_xml(etags) query = 'uploadId=%s' % upload_id status, headers, body = \ self.conn.make_request('POST', bucket, key, body=xml, query=query) self.assertEqual(status, 200) # multi parts with all parts except the first part less than min # segment size query = 'uploads' status, headers, body = \ self.conn.make_request('POST', bucket, key, query=query) elem = fromstring(body, 'InitiateMultipartUploadResult') upload_id = elem.find('UploadId').text etags = [] body_size = [MIN_SEGMENT_SIZE, MIN_SEGMENT_SIZE - 1, 2] for i in xrange(1, 3): query = 'partNumber=%s&uploadId=%s' % (i, upload_id) status, headers, body = \ self.conn.make_request('PUT', bucket, key, query=query, body='A' * body_size[i]) etags.append(headers['etag']) xml = self._gen_comp_xml(etags) query = 'uploadId=%s' % upload_id status, headers, body = \ self.conn.make_request('POST', bucket, key, body=xml, query=query) self.assertEqual(get_error_code(body), 'EntityTooSmall') # multi parts with all parts except last part more than min segment # size query = 'uploads' status, headers, body = \ self.conn.make_request('POST', bucket, key, query=query) elem = fromstring(body, 'InitiateMultipartUploadResult') upload_id = elem.find('UploadId').text etags = [] body_size = [MIN_SEGMENT_SIZE, MIN_SEGMENT_SIZE, 2] for i in xrange(1, 3): query = 'partNumber=%s&uploadId=%s' % (i, upload_id) status, headers, body = \ self.conn.make_request('PUT', bucket, key, query=query, body='A' * body_size[i]) etags.append(headers['etag']) xml = self._gen_comp_xml(etags) query = 'uploadId=%s' % upload_id status, headers, body = \ self.conn.make_request('POST', bucket, key, body=xml, query=query) self.assertEqual(status, 200)
def test_service_error(self): auth_error_conn = Connection(aws_secret_key='invalid') status, headers, body = auth_error_conn.make_request('GET') self.assertEquals(get_error_code(body), 'SignatureDoesNotMatch')
def test_service_error(self): auth_error_conn = Connection(aws_secret_key='invalid') status, headers, body = auth_error_conn.make_request('GET') self.assertEquals(get_error_code(body), 'SignatureDoesNotMatch') self.assertEquals(headers['content-type'], 'application/xml')
def test_complete_multi_upload_error(self): bucket = 'bucket' keys = ['obj', 'obj2'] self.conn.make_request('PUT', bucket) query = 'uploads' status, headers, body = \ self.conn.make_request('POST', bucket, keys[0], query=query) elem = fromstring(body, 'InitiateMultipartUploadResult') upload_id = elem.find('UploadId').text etags = [] for i in xrange(1, 3): query = 'partNumber=%s&uploadId=%s' % (i, upload_id) status, headers, body = \ self.conn.make_request('PUT', bucket, keys[0], query=query) etags.append(headers['etag']) xml = self._gen_comp_xml(etags) # part 1 too small query = 'uploadId=%s' % upload_id status, headers, body = \ self.conn.make_request('POST', bucket, keys[0], body=xml, query=query) self.assertEqual(get_error_code(body), 'EntityTooSmall') # invalid credentials auth_error_conn = Connection(aws_secret_key='invalid') status, headers, body = \ auth_error_conn.make_request('POST', bucket, keys[0], body=xml, query=query) self.assertEqual(get_error_code(body), 'SignatureDoesNotMatch') # wrong/missing bucket status, headers, body = \ self.conn.make_request('POST', 'nothing', keys[0], query=query) self.assertEqual(get_error_code(body), 'NoSuchBucket') # wrong upload ID query = 'uploadId=%s' % 'nothing' status, headers, body = \ self.conn.make_request('POST', bucket, keys[0], body=xml, query=query) self.assertEqual(get_error_code(body), 'NoSuchUpload') # without Part tag in xml query = 'uploadId=%s' % upload_id xml = self._gen_comp_xml([]) status, headers, body = \ self.conn.make_request('POST', bucket, keys[0], body=xml, query=query) self.assertEqual(get_error_code(body), 'MalformedXML') # with invalid etag in xml invalid_etag = 'invalid' xml = self._gen_comp_xml([invalid_etag]) status, headers, body = \ self.conn.make_request('POST', bucket, keys[0], body=xml, query=query) self.assertEqual(get_error_code(body), 'InvalidPart') # without part in Swift query = 'uploads' status, headers, body = \ self.conn.make_request('POST', bucket, keys[1], query=query) elem = fromstring(body, 'InitiateMultipartUploadResult') upload_id = elem.find('UploadId').text query = 'uploadId=%s' % upload_id xml = self._gen_comp_xml([etags[0]]) status, headers, body = \ self.conn.make_request('POST', bucket, keys[1], body=xml, query=query) self.assertEqual(get_error_code(body), 'InvalidPart')
def test_delete_multi_objects_error(self): bucket = 'bucket' put_objects = ['obj'] self._prepare_test_delete_multi_objects(bucket, put_objects) xml = self._gen_multi_delete_xml(put_objects) content_md5 = calculate_md5(xml) query = 'delete' auth_error_conn = Connection(aws_secret_key='invalid') status, headers, body = \ auth_error_conn.make_request('POST', bucket, body=xml, headers={ 'Content-MD5': content_md5 }, query=query) self.assertEquals(get_error_code(body), 'SignatureDoesNotMatch') status, headers, body = \ self.conn.make_request('POST', 'nothing', body=xml, headers={'Content-MD5': content_md5}, query=query) self.assertEquals(get_error_code(body), 'NoSuchBucket') # without Object tag xml = self._gen_invalid_multi_delete_xml() content_md5 = calculate_md5(xml) status, headers, body = \ self.conn.make_request('POST', bucket, body=xml, headers={'Content-MD5': content_md5}, query=query) self.assertEquals(get_error_code(body), 'MalformedXML') # without value of Key tag xml = self._gen_invalid_multi_delete_xml(hasObjectTag=True) content_md5 = calculate_md5(xml) status, headers, body = \ self.conn.make_request('POST', bucket, body=xml, headers={'Content-MD5': content_md5}, query=query) self.assertEquals(get_error_code(body), 'UserKeyMustBeSpecified') # specified number of objects are over CONF.max_multi_delete_objects # (Default 1000), but xml size is smaller than 61365 bytes. req_objects = ['obj%s' for var in xrange(1001)] xml = self._gen_multi_delete_xml(req_objects) self.assertTrue(len(xml.encode('utf-8')) <= MAX_MULTI_DELETE_BODY_SIZE) content_md5 = calculate_md5(xml) status, headers, body = \ self.conn.make_request('POST', bucket, body=xml, headers={'Content-MD5': content_md5}, query=query) self.assertEquals(get_error_code(body), 'MalformedXML') # specified xml size is over 61365 bytes, but number of objects are # smaller than CONF.max_multi_delete_objects. obj = 'a' * 1024 req_objects = [obj + str(var) for var in xrange(999)] xml = self._gen_multi_delete_xml(req_objects) self.assertTrue(len(xml.encode('utf-8')) > MAX_MULTI_DELETE_BODY_SIZE) content_md5 = calculate_md5(xml) status, headers, body = \ self.conn.make_request('POST', bucket, body=xml, headers={'Content-MD5': content_md5}, query=query) self.assertEquals(get_error_code(body), 'MalformedXML')
def test_service_error_signature_not_match(self): auth_error_conn = Connection(aws_secret_key='invalid') status, headers, body = auth_error_conn.make_request('GET') self.assertEqual(get_error_code(body), 'SignatureDoesNotMatch') self.assertEqual(headers['content-type'], 'application/xml')
def test_complete_multi_upload_error(self): bucket = 'bucket' keys = ['obj', 'obj2'] self.conn.make_request('PUT', bucket) query = 'uploads' status, headers, body = \ self.conn.make_request('POST', bucket, keys[0], query=query) elem = fromstring(body, 'InitiateMultipartUploadResult') upload_id = elem.find('UploadId').text etags = [] for i in xrange(1, 3): query = 'partNumber=%s&uploadId=%s' % (i, upload_id) status, headers, body = \ self.conn.make_request('PUT', bucket, keys[0], query=query) etags.append(headers['etag']) xml = self._gen_comp_xml(etags) query = 'uploadId=%s' % upload_id auth_error_conn = Connection(aws_secret_key='invalid') status, headers, body = \ auth_error_conn.make_request('POST', bucket, keys[0], body=xml, query=query) self.assertEquals(get_error_code(body), 'SignatureDoesNotMatch') status, headers, body = \ self.conn.make_request('POST', 'nothing', keys[0], query=query) self.assertEquals(get_error_code(body), 'NoSuchBucket') query = 'uploadId=%s' % 'nothing' status, headers, body = \ self.conn.make_request('POST', bucket, keys[0], body=xml, query=query) self.assertEquals(get_error_code(body), 'NoSuchUpload') # without Part tag in xml query = 'uploadId=%s' % upload_id xml = self._gen_comp_xml([]) status, headers, body = \ self.conn.make_request('POST', bucket, keys[0], body=xml, query=query) self.assertEquals(get_error_code(body), 'MalformedXML') # with ivalid etag in xml invalid_etag = 'invalid' xml = self._gen_comp_xml([invalid_etag]) status, headers, body = \ self.conn.make_request('POST', bucket, keys[0], body=xml, query=query) self.assertEquals(get_error_code(body), 'InvalidPart') # without part in Swift query = 'uploads' status, headers, body = \ self.conn.make_request('POST', bucket, keys[1], query=query) elem = fromstring(body, 'InitiateMultipartUploadResult') upload_id = elem.find('UploadId').text query = 'uploadId=%s' % upload_id xml = self._gen_comp_xml([etags[0]]) status, headers, body = \ self.conn.make_request('POST', bucket, keys[1], body=xml, query=query) self.assertEquals(get_error_code(body), 'InvalidPart')