def test_delete_multi_objects_with_quiet(self): bucket = 'bucket' put_objects = ['obj'] query = 'delete' # with Quiet true quiet = 'true' self._prepare_test_delete_multi_objects(bucket, put_objects) xml = self._gen_multi_delete_xml(put_objects, quiet) 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(status, 200) elem = fromstring(body, 'DeleteResult') resp_objects = elem.findall('Deleted') self.assertEquals(len(resp_objects), 0) # with Quiet false quiet = 'false' self._prepare_test_delete_multi_objects(bucket, put_objects) xml = self._gen_multi_delete_xml(put_objects, quiet) 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(status, 200) elem = fromstring(body, 'DeleteResult') resp_objects = elem.findall('Deleted') self.assertEquals(len(resp_objects), 1)
def test_put_object_content_md5(self): obj = 'object' content = 'abcdefghij' etag = md5(content).hexdigest() headers = {'Content-MD5': calculate_md5(content)} status, headers, body = \ self.conn.make_request('PUT', self.bucket, obj, headers, content) self.assertEqual(status, 200) self.assertCommonResponseHeaders(headers) self._assertObjectEtag(self.bucket, obj, etag)
def test_put_object_content_md5(self): obj = 'object' content = 'abcdefghij' etag = md5(content).hexdigest() headers = {'Content-MD5': calculate_md5(content)} status, headers, body = \ self.conn.make_request('PUT', self.bucket, obj, headers, content) self.assertEquals(status, 200) self.assertCommonResponseHeaders(headers) self._assertObjectEtag(self.bucket, obj, etag)
def test_delete_multi_objects(self): bucket = 'bucket' put_objects = ['obj%s' % var for var in xrange(4)] self._prepare_test_delete_multi_objects(bucket, put_objects) query = 'delete' # Delete an object via MultiDelete API req_objects = ['obj0'] xml = self._gen_multi_delete_xml(req_objects) 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(status, 200) self.assertCommonResponseHeaders(headers) self.assertTrue(headers['content-type'] is not None) self.assertEquals(headers['content-length'], str(len(body))) elem = fromstring(body) resp_objects = elem.findall('Deleted') self.assertEquals(len(resp_objects), len(req_objects)) for o in resp_objects: self.assertTrue(o.find('Key').text in req_objects) # Delete 2 objects via MultiDelete API req_objects = ['obj1', 'obj2'] xml = self._gen_multi_delete_xml(req_objects) 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(status, 200) elem = fromstring(body, 'DeleteResult') resp_objects = elem.findall('Deleted') self.assertEquals(len(resp_objects), len(req_objects)) for o in resp_objects: self.assertTrue(o.find('Key').text in req_objects) # Delete 2 objects via MultiDelete API but one (obj4) doesn't exist. req_objects = ['obj3', 'obj4'] xml = self._gen_multi_delete_xml(req_objects) 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(status, 200) elem = fromstring(body, 'DeleteResult') resp_objects = elem.findall('Deleted') # S3 assumes a NoSuchKey object as deleted. self.assertEquals(len(resp_objects), len(req_objects)) for o in resp_objects: self.assertTrue(o.find('Key').text in req_objects) # Delete 2 objects via MultiDelete API but no objects exist req_objects = ['obj4', 'obj5'] xml = self._gen_multi_delete_xml(req_objects) 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(status, 200) elem = fromstring(body, 'DeleteResult') resp_objects = elem.findall('Deleted') self.assertEquals(len(resp_objects), len(req_objects)) for o in resp_objects: self.assertTrue(o.find('Key').text in req_objects)
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')