Merge "Add tests for testing swift bulk middleware"
This commit is contained in:
commit
c3d358b5ca
136
tempest/api/object_storage/test_account_bulk.py
Normal file
136
tempest/api/object_storage/test_account_bulk.py
Normal file
@ -0,0 +1,136 @@
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
|
||||
# Copyright 2013 NTT Corporation
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import tarfile
|
||||
import tempfile
|
||||
|
||||
from tempest.api.object_storage import base
|
||||
from tempest.common import custom_matchers
|
||||
from tempest import test
|
||||
|
||||
|
||||
class BulkTest(base.BaseObjectTest):
|
||||
|
||||
def setUp(self):
|
||||
super(BulkTest, self).setUp()
|
||||
self.containers = []
|
||||
|
||||
def tearDown(self):
|
||||
self.delete_containers(self.containers)
|
||||
super(BulkTest, self).tearDown()
|
||||
|
||||
def _create_archive(self):
|
||||
# Create an archived file for bulk upload testing.
|
||||
# Directory and files contained in the directory correspond to
|
||||
# container and subsidiary objects.
|
||||
tmp_dir = tempfile.mkdtemp()
|
||||
tmp_file = tempfile.mkstemp(dir=tmp_dir)
|
||||
|
||||
# Extract a container name and an object name
|
||||
container_name = tmp_dir.split("/")[-1]
|
||||
object_name = tmp_file[1].split("/")[-1]
|
||||
|
||||
# Create tar file
|
||||
tarpath = tempfile.NamedTemporaryFile(suffix=".tar")
|
||||
tar = tarfile.open(None, 'w', tarpath)
|
||||
tar.add(tmp_dir, arcname=container_name)
|
||||
tar.close()
|
||||
tarpath.flush()
|
||||
|
||||
return tarpath.name, container_name, object_name
|
||||
|
||||
@test.attr(type='gate')
|
||||
def test_extract_archive(self):
|
||||
# Test bulk operation of file upload with an archived file
|
||||
filepath, container_name, object_name = self._create_archive()
|
||||
|
||||
params = {'extract-archive': 'tar'}
|
||||
with open(filepath) as fh:
|
||||
mydata = fh.read()
|
||||
resp, body = self.account_client.create_account(data=mydata,
|
||||
params=params)
|
||||
|
||||
self.containers.append(container_name)
|
||||
|
||||
self.assertIn(int(resp['status']), test.HTTP_SUCCESS)
|
||||
|
||||
# When uploading an archived file with the bulk operation, the response
|
||||
# does not contain 'content-length' header. This is the special case,
|
||||
# therefore the existence of response headers is checked without
|
||||
# custom matcher.
|
||||
self.assertIn('transfer-encoding', resp)
|
||||
self.assertIn('content-type', resp)
|
||||
self.assertIn('x-trans-id', resp)
|
||||
self.assertIn('date', resp)
|
||||
|
||||
# Check only the format of common headers with custom matcher
|
||||
self.assertThat(resp, custom_matchers.AreAllWellFormatted())
|
||||
|
||||
param = {'format': 'json'}
|
||||
resp, body = self.account_client.list_account_containers(param)
|
||||
|
||||
self.assertIn(int(resp['status']), test.HTTP_SUCCESS)
|
||||
self.assertHeaders(resp, 'Account', 'GET')
|
||||
|
||||
self.assertIn(container_name, [b['name'] for b in body])
|
||||
|
||||
param = {'format': 'json'}
|
||||
resp, contents_list = self.container_client.list_container_contents(
|
||||
container_name, param)
|
||||
|
||||
self.assertIn(int(resp['status']), test.HTTP_SUCCESS)
|
||||
self.assertHeaders(resp, 'Container', 'GET')
|
||||
|
||||
self.assertIn(object_name, [c['name'] for c in contents_list])
|
||||
|
||||
@test.attr(type='gate')
|
||||
def test_bulk_delete(self):
|
||||
# Test bulk operation of deleting multiple files
|
||||
filepath, container_name, object_name = self._create_archive()
|
||||
|
||||
params = {'extract-archive': 'tar'}
|
||||
with open(filepath) as fh:
|
||||
mydata = fh.read()
|
||||
resp, body = self.account_client.create_account(data=mydata,
|
||||
params=params)
|
||||
|
||||
data = '%s/%s\n%s' % (container_name, object_name, container_name)
|
||||
params = {'bulk-delete': ''}
|
||||
resp, body = self.account_client.delete_account(data=data,
|
||||
params=params)
|
||||
|
||||
self.assertIn(int(resp['status']), test.HTTP_SUCCESS)
|
||||
|
||||
# When deleting multiple files using the bulk operation, the response
|
||||
# does not contain 'content-length' header. This is the special case,
|
||||
# therefore the existence of response headers is checked without
|
||||
# custom matcher.
|
||||
self.assertIn('transfer-encoding', resp)
|
||||
self.assertIn('content-type', resp)
|
||||
self.assertIn('x-trans-id', resp)
|
||||
self.assertIn('date', resp)
|
||||
|
||||
# Check only the format of common headers with custom matcher
|
||||
self.assertThat(resp, custom_matchers.AreAllWellFormatted())
|
||||
|
||||
# Check if a container is deleted
|
||||
param = {'format': 'txt'}
|
||||
resp, body = self.account_client.list_account_containers(param)
|
||||
|
||||
self.assertIn(int(resp['status']), test.HTTP_SUCCESS)
|
||||
self.assertHeaders(resp, 'Account', 'GET')
|
||||
|
||||
self.assertNotIn(container_name, body)
|
@ -131,6 +131,8 @@ class AreAllWellFormatted(object):
|
||||
return InvalidFormat(key, value)
|
||||
elif key == 'etag' and not value.isalnum():
|
||||
return InvalidFormat(key, value)
|
||||
elif key == 'transfer-encoding' and not value == 'chunked':
|
||||
return InvalidFormat(key, value)
|
||||
|
||||
return None
|
||||
|
||||
|
@ -291,8 +291,8 @@ class RestClient(object):
|
||||
def get(self, url, headers=None):
|
||||
return self.request('GET', url, headers)
|
||||
|
||||
def delete(self, url, headers=None):
|
||||
return self.request('DELETE', url, headers)
|
||||
def delete(self, url, headers=None, body=None):
|
||||
return self.request('DELETE', url, headers, body)
|
||||
|
||||
def patch(self, url, body, headers):
|
||||
return self.request('PATCH', url, headers, body)
|
||||
|
@ -31,6 +31,37 @@ class AccountClient(RestClient):
|
||||
self.service = CONF.object_storage.catalog_type
|
||||
self.format = 'json'
|
||||
|
||||
def create_account(self, data=None,
|
||||
params=None,
|
||||
metadata={},
|
||||
remove_metadata={},
|
||||
metadata_prefix='X-Account-Meta-',
|
||||
remove_metadata_prefix='X-Remove-Account-Meta-'):
|
||||
"""Create an account."""
|
||||
url = ''
|
||||
if params:
|
||||
url += '?%s' % urllib.urlencode(params)
|
||||
|
||||
headers = {}
|
||||
for key in metadata:
|
||||
headers[metadata_prefix + key] = metadata[key]
|
||||
for key in remove_metadata:
|
||||
headers[remove_metadata_prefix + key] = remove_metadata[key]
|
||||
|
||||
resp, body = self.put(url, data, headers)
|
||||
return resp, body
|
||||
|
||||
def delete_account(self, data=None, params=None):
|
||||
"""Delete an account."""
|
||||
url = ''
|
||||
if params:
|
||||
if 'bulk-delete' in params:
|
||||
url += 'bulk-delete&'
|
||||
url = '?%s%s' % (url, urllib.urlencode(params))
|
||||
|
||||
resp, body = self.delete(url, headers=None, body=data)
|
||||
return resp, body
|
||||
|
||||
def list_account_metadata(self):
|
||||
"""
|
||||
HEAD on the storage URL
|
||||
@ -91,6 +122,8 @@ class AccountClient(RestClient):
|
||||
|
||||
url = '?' + urllib.urlencode(params)
|
||||
resp, body = self.get(url)
|
||||
|
||||
if params and params.get('format') == 'json':
|
||||
body = json.loads(body)
|
||||
return resp, body
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user