# Copyright 2012 OpenStack Foundation
# All Rights Reserved.
#
# 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 random
import testtools
from tempest.api.object_storage import base
from tempest.common import custom_matchers
from tempest.common import object_storage
from tempest import config
from tempest.lib.common.utils import data_utils
from tempest.lib import decorators
CONF = config.CONF
[docs]
class AccountTest(base.BaseObjectTest):
"""Test account metadata and containers"""
credentials = [['operator', CONF.object_storage.operator_role],
['operator_alt', CONF.object_storage.operator_role]]
containers = []
@classmethod
def setup_credentials(cls):
super(AccountTest, cls).setup_credentials()
cls.os_operator = cls.os_roles_operator_alt
@classmethod
def resource_setup(cls):
super(AccountTest, cls).resource_setup()
for i in range(ord('a'), ord('f') + 1):
name = data_utils.rand_name(
prefix=CONF.resource_name_prefix,
name='%s-' % bytes((i,)))
cls.container_client.update_container(name)
cls.addClassResourceCleanup(object_storage.delete_containers,
[name],
cls.container_client,
cls.object_client)
cls.containers.append(name)
cls.containers_count = len(cls.containers)
[docs]
@decorators.attr(type='smoke')
@decorators.idempotent_id('3499406a-ae53-4f8c-b43a-133d4dc6fe3f')
def test_list_containers(self):
"""Test listing containers"""
resp, container_list = self.account_client.list_account_containers()
self.assertHeaders(resp, 'Account', 'GET')
self.assertIsNotNone(container_list)
for container_name in self.containers:
self.assertIn(str(container_name).encode('utf-8'),
container_list)
[docs]
@decorators.idempotent_id('884ec421-fbad-4fcc-916b-0580f2699565')
def test_list_no_containers(self):
"""Test listing containers for an account without container"""
# To test listing no containers, create new user other than
# the base user of this instance.
resp, container_list = \
self.os_operator.account_client.list_account_containers()
# When sending a request to an account which has not received a PUT
# container request, the response does not contain 'accept-ranges'
# header. This is a special case, therefore the existence of response
# headers is checked without custom matcher.
#
# As the expected response is 204 No Content, Content-Length presence
# is not checked here intentionally. According to RFC 7230 a server
# MUST NOT send the header in such responses. Thus, clients should not
# depend on this header. However, the standard does not require them
# to validate the server's behavior. We leverage that to not refuse
# any implementation violating it like Swift [1] or some versions of
# Ceph RadosGW [2].
# [1] https://bugs.launchpad.net/swift/+bug/1537811
# [2] http://tracker.ceph.com/issues/13582
self.assertIn('x-timestamp', resp)
self.assertIn('x-account-bytes-used', resp)
self.assertIn('x-account-container-count', resp)
self.assertIn('x-account-object-count', 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())
self.assertEmpty(container_list)
[docs]
@decorators.idempotent_id('6eb04a6a-4860-4e31-ba91-ea3347d76b58')
@testtools.skipIf(
not CONF.object_storage_feature_enabled.discoverability,
'Discoverability function is disabled')
def test_list_extensions(self):
"""Test listing capabilities"""
resp = self.capabilities_client.list_capabilities()
self.assertThat(resp, custom_matchers.AreAllWellFormatted())
[docs]
@decorators.idempotent_id('5cfa4ab2-4373-48dd-a41f-a532b12b08b2')
def test_list_containers_with_limit(self):
"""Test listing containers with limit parameter
Listing containers limited to one of them, half of them, and then all
of them.
"""
for limit in (1, self.containers_count // 2,
self.containers_count):
params = {'limit': limit}
resp, container_list = \
self.account_client.list_account_containers(params=params)
self.assertHeaders(resp, 'Account', 'GET')
self.assertEqual(len(container_list), limit)
[docs]
@decorators.idempotent_id('638f876d-6a43-482a-bbb3-0840bca101c6')
def test_list_containers_with_marker(self):
"""Test listing containers with marker parameter
First expect to get 0 container as we specified the last container
as marker, second expect to get the bottom half of the containers.
"""
params = {'marker': self.containers[-1]}
resp, container_list = \
self.account_client.list_account_containers(params=params)
self.assertHeaders(resp, 'Account', 'GET')
self.assertEmpty(container_list)
params = {'marker': self.containers[self.containers_count // 2]}
resp, container_list = \
self.account_client.list_account_containers(params=params)
self.assertHeaders(resp, 'Account', 'GET')
self.assertEqual(len(container_list),
self.containers_count // 2 - 1)
[docs]
@decorators.idempotent_id('5ca164e4-7bde-43fa-bafb-913b53b9e786')
def test_list_containers_with_end_marker(self):
"""Test listing containers with end_marker parameter
First expect to get 0 container as we specified first container as
end_marker, second expect to get the top half of the containers
"""
params = {'end_marker': self.containers[0]}
resp, container_list = \
self.account_client.list_account_containers(params=params)
self.assertHeaders(resp, 'Account', 'GET')
self.assertEmpty(container_list)
params = {'end_marker': self.containers[self.containers_count // 2]}
resp, container_list = \
self.account_client.list_account_containers(params=params)
self.assertHeaders(resp, 'Account', 'GET')
self.assertEqual(len(container_list), self.containers_count // 2)
[docs]
@decorators.idempotent_id('ac8502c2-d4e4-4f68-85a6-40befea2ef5e')
def test_list_containers_with_marker_and_end_marker(self):
"""Test listing containers with marker and end_marker parameter
If we use the first container as marker, and the last container as
end_marker, then we should get all containers excluding the first one
and the last one.
"""
params = {'marker': self.containers[0],
'end_marker': self.containers[self.containers_count - 1]}
resp, container_list = self.account_client.list_account_containers(
params=params)
self.assertHeaders(resp, 'Account', 'GET')
self.assertEqual(len(container_list), self.containers_count - 2)
[docs]
@decorators.idempotent_id('f7064ae8-dbcc-48da-b594-82feef6ea5af')
def test_list_containers_with_limit_and_marker(self):
"""Test listing containers combining marker and limit parameter
Result are always limited by the limit whatever the marker.
"""
for marker in random.choice(self.containers):
limit = random.randint(0, self.containers_count - 1)
params = {'marker': marker,
'limit': limit}
resp, container_list = \
self.account_client.list_account_containers(params=params)
self.assertHeaders(resp, 'Account', 'GET')
self.assertLessEqual(len(container_list), limit,
str(container_list))
[docs]
@decorators.idempotent_id('888a3f0e-7214-4806-8e50-5e0c9a69bb5e')
def test_list_containers_with_limit_and_end_marker(self):
"""Test listing containers combining end_marker and limit parameter
Result are always limited by the limit whatever the end_marker.
"""
# list containers combining limit and end_marker param
limit = random.randint(1, self.containers_count)
params = {'limit': limit,
'end_marker': self.containers[self.containers_count // 2]}
resp, container_list = self.account_client.list_account_containers(
params=params)
self.assertHeaders(resp, 'Account', 'GET')
self.assertEqual(len(container_list),
min(limit, self.containers_count // 2))
[docs]
@decorators.idempotent_id('8cf98d9c-e3a0-4e44-971b-c87656fdddbd')
def test_list_containers_with_limit_and_marker_and_end_marker(self):
"""Test listing containers combining marker and end_marker and limit
Result are always limited by the limit whatever the marker and the
end_marker.
"""
limit = random.randint(1, self.containers_count)
params = {'limit': limit,
'marker': self.containers[0],
'end_marker': self.containers[self.containers_count - 1]}
resp, container_list = self.account_client.list_account_containers(
params=params)
self.assertHeaders(resp, 'Account', 'GET')
self.assertEqual(len(container_list),
min(limit, self.containers_count - 2))
[docs]
@decorators.idempotent_id('365e6fc7-1cfe-463b-a37c-8bd08d47b6aa')
def test_list_containers_with_prefix(self):
"""Test listing containers that have a name starting with a prefix"""
prefix = 'tempest-a'
params = {'prefix': prefix}
resp, container_list = self.account_client.list_account_containers(
params=params)
self.assertHeaders(resp, 'Account', 'GET')
for container in container_list:
self.assertEqual(True, container.decode(
'utf-8').startswith(prefix))
[docs]
@decorators.idempotent_id('b1811cff-d1ed-4c15-a52e-efd8de41cf34')
def test_list_containers_reverse_order(self):
"""Test listing containers in reverse order"""
_, orig_container_list = self.account_client.list_account_containers()
params = {'reverse': True}
resp, container_list = self.account_client.list_account_containers(
params=params)
self.assertHeaders(resp, 'Account', 'GET')
self.assertEqual(sorted(orig_container_list, reverse=True),
container_list)