Merge "[Swift] Add base for Swift API Benchmarks: Patch-2"

This commit is contained in:
Jenkins 2015-04-22 22:32:06 +00:00 committed by Gerrit Code Review
commit 87315aed09
18 changed files with 914 additions and 3 deletions

View File

@ -750,3 +750,60 @@
users:
tenants: 2
users_per_tenant: 2
SwiftObjects.create_container_and_object_then_list_objects:
-
args:
objects_per_container: 2
object_size: 5120
runner:
type: "constant"
times: 2
concurrency: 2
context:
users:
tenants: 1
users_per_tenant: 1
roles:
- "admin"
sla:
failure_rate:
max: 0
SwiftObjects.create_container_and_object_then_delete_all:
-
args:
objects_per_container: 5
object_size: 102400
runner:
type: "constant"
times: 4
concurrency: 2
context:
users:
tenants: 1
users_per_tenant: 1
roles:
- "admin"
sla:
failure_rate:
max: 0
SwiftObjects.create_container_and_object_then_download_object:
-
args:
objects_per_container: 5
object_size: 1024
runner:
type: "constant"
times: 6
concurrency: 3
context:
users:
tenants: 1
users_per_tenant: 1
roles:
- "admin"
sla:
failure_rate:
max: 0

View File

@ -345,6 +345,53 @@ class DesignateServer(SynchronizedDeletion, base.ResourceManager):
pass
# SWIFT
_swift_order = get_order(1000)
class SwiftMixin(SynchronizedDeletion, base.ResourceManager):
def _manager(self):
client = self._admin_required and self.admin or self.user
return getattr(client, self._service)()
def id(self):
return self.raw_resource
def delete(self):
delete_method = getattr(self._manager(), "delete_%s" % self._resource)
# NOTE(weiwu): *self.raw_resource is required because for deleting
# container we are passing only container name, to delete object we
# should pass as first argument container and second is object name.
delete_method(*self.raw_resource)
@base.resource("swift", "object", order=next(_swift_order),
tenant_resource=True)
class SwiftObject(SwiftMixin):
def list(self):
object_list = []
containers = self._manager().get_account(full_listing=True)[1]
for con in containers:
objects = self._manager().get_container(con["name"],
full_listing=True)[1]
for obj in objects:
raw_resource = [con["name"], obj["name"]]
object_list.append(raw_resource)
return object_list
@base.resource("swift", "container", order=next(_swift_order),
tenant_resource=True)
class SwiftContainer(SwiftMixin):
def list(self):
containers = self._manager().get_account(full_listing=True)[1]
return [[con["name"]] for con in containers]
# MISTRAL
@base.resource("mistral", "workbooks", order=1100, tenant_resource=True)

View File

@ -0,0 +1,124 @@
# Copyright 2015: Cisco Systems, Inc.
# 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 tempfile
from rally.benchmark.scenarios import base
from rally.benchmark.scenarios.swift import utils
from rally.benchmark import validation
from rally import consts
class SwiftObjects(utils.SwiftScenario):
"""Benchmark scenarios for Swift Objects."""
@validation.required_services(consts.Service.SWIFT)
@validation.required_openstack(users=True)
@base.scenario(context={"cleanup": ["swift"]})
def create_container_and_object_then_list_objects(
self, objects_per_container=1,
object_size=1024, **kwargs):
"""Create container and objects then list all objects.
:param objects_per_container: int, number of objects to upload
:param object_size: int, temporary local object size
:param kwargs: dict, optional parameters to create container
"""
key_suffix = "object"
if objects_per_container > 1:
key_suffix = "%i_objects" % objects_per_container
container_name = None
with tempfile.TemporaryFile() as dummy_file:
# set dummy file to specified object size
dummy_file.truncate(object_size)
container_name = self._create_container(**kwargs)
with base.AtomicAction(self, "swift.create_%s" % key_suffix):
for i in range(objects_per_container):
dummy_file.seek(0)
self._upload_object(container_name, dummy_file,
atomic_action=False)
self._list_objects(container_name)
@validation.required_services(consts.Service.SWIFT)
@validation.required_openstack(users=True)
@base.scenario(context={"cleanup": ["swift"]})
def create_container_and_object_then_delete_all(
self, objects_per_container=1,
object_size=1024, **kwargs):
"""Create container and objects then delete everything created.
:param objects_per_container: int, number of objects to upload
:param object_size: int, temporary local object size
:param kwargs: dict, optional parameters to create container
"""
key_suffix = "object"
if objects_per_container > 1:
key_suffix = "%i_objects" % objects_per_container
container_name = None
objects_list = []
with tempfile.TemporaryFile() as dummy_file:
# set dummy file to specified object size
dummy_file.truncate(object_size)
container_name = self._create_container(**kwargs)
with base.AtomicAction(self, "swift.create_%s" % key_suffix):
for i in range(objects_per_container):
dummy_file.seek(0)
object_name = self._upload_object(container_name,
dummy_file,
atomic_action=False)[1]
objects_list.append(object_name)
with base.AtomicAction(self, "swift.delete_%s" % key_suffix):
for object_name in objects_list:
self._delete_object(container_name, object_name,
atomic_action=False)
self._delete_container(container_name)
@validation.required_services(consts.Service.SWIFT)
@validation.required_openstack(users=True)
@base.scenario(context={"cleanup": ["swift"]})
def create_container_and_object_then_download_object(
self, objects_per_container=1,
object_size=1024, **kwargs):
"""Create container and objects then download all objects.
:param objects_per_container: int, number of objects to upload
:param object_size: int, temporary local object size
:param kwargs: dict, optional parameters to create container
"""
key_suffix = "object"
if objects_per_container > 1:
key_suffix = "%i_objects" % objects_per_container
container_name = None
objects_list = []
with tempfile.TemporaryFile() as dummy_file:
# set dummy file to specified object size
dummy_file.truncate(object_size)
container_name = self._create_container(**kwargs)
with base.AtomicAction(self, "swift.create_%s" % key_suffix):
for i in range(objects_per_container):
dummy_file.seek(0)
object_name = self._upload_object(container_name,
dummy_file,
atomic_action=False)[1]
objects_list.append(object_name)
with base.AtomicAction(self, "swift.download_%s" % key_suffix):
for object_name in objects_list:
self._download_object(container_name, object_name,
atomic_action=False)

View File

@ -0,0 +1,163 @@
# Copyright 2015: Cisco Systems, Inc.
# 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.
from rally.benchmark.scenarios import base
class SwiftScenario(base.Scenario):
"""Base class for Swift scenarios with basic atomic actions."""
@base.atomic_action_timer("swift.list_containers")
def _list_containers(self, full_listing=True, **kwargs):
"""Return list of containers.
:param full_listing: bool, enable unlimit number of listing returned
:param kwargs: dict, other optional parameters to get_account
:returns: tuple, (dict of response headers, a list of containers)
"""
return self.clients("swift").get_account(full_listing=full_listing,
**kwargs)
def _create_container(self, container_name=None, public=False,
atomic_action=True, **kwargs):
"""Create a new container with given name.
:param container_name: str, name of the container to create
:param public: bool, set container as public
:param atomic_action: bool, enable create container to be tracked as an
atomic action
:param kwargs: dict, other optional parameters to put_container
:returns: container name
"""
if public:
kwargs.setdefault("headers", {})
kwargs["headers"].setdefault("X-Container-Read", ".r:*,.rlistings")
if container_name is None:
container_name = self._generate_random_name(
prefix="rally_container_")
if atomic_action:
with base.AtomicAction(self, "swift.create_container"):
self.clients("swift").put_container(container_name, **kwargs)
else:
self.clients("swift").put_container(container_name, **kwargs)
return container_name
def _delete_container(self, container_name, atomic_action=True, **kwargs):
"""Delete a container with given name.
:param container_name: str, name of the container to delete
:param atomic_action: bool, enable delete container to be tracked as an
atomic action
:param kwargs: dict, other optional parameters to delete_container
"""
if atomic_action:
with base.AtomicAction(self, "swift.delete_container"):
self.clients("swift").delete_container(container_name,
**kwargs)
else:
self.clients("swift").delete_container(container_name, **kwargs)
def _list_objects(self, container_name, full_listing=True,
atomic_action=True, **kwargs):
"""Return objects inside container.
:param container_name: str, name of the container to make the list
objects operation against
:param full_listing: bool, enable unlimit number of listing returned
:param atomic_action: bool, enable list objects to be tracked as an
atomic action
:param kwargs: dict, other optional parameters to get_container
:returns: tuple, (dict of response headers, a list of objects)
"""
if atomic_action:
with base.AtomicAction(self, "swift.list_objects"):
return self.clients("swift").get_container(
container_name, full_listing=full_listing,
**kwargs)
return self.clients("swift").get_container(container_name,
full_listing=full_listing,
**kwargs)
def _upload_object(self, container_name, content, object_name=None,
atomic_action=True, **kwargs):
"""Upload content to a given container.
:param container_name: str, name of the container to upload object to
:param content: file stream, content to upload
:param object_name: str, name of the object to upload
:param atomic_action: bool, enable upload object to be tracked as an
atomic action
:param kwargs: dict, other optional parameters to put_object
:returns: tuple, (etag and object name)
"""
if object_name is None:
object_name = self._generate_random_name(prefix="rally_object_")
if atomic_action:
with base.AtomicAction(self, "swift.upload_object"):
return (self.clients("swift").put_object(container_name,
object_name, content,
**kwargs),
object_name)
return (self.clients("swift").put_object(container_name, object_name,
content, **kwargs),
object_name)
def _download_object(self, container_name, object_name, atomic_action=True,
**kwargs):
"""Download object from container.
:param container_name: str, name of the container to download object
from
:param object_name: str, name of the object to download
:param atomic_action: bool, enable download object to be tracked as an
atomic action
:param kwargs: dict, other optional parameters to get_object
:returns: tuple, (dict of response headers, the object's contents)
"""
if atomic_action:
with base.AtomicAction(self, "swift.download_object"):
return self.clients("swift").get_object(container_name,
object_name, **kwargs)
return self.clients("swift").get_object(container_name, object_name,
**kwargs)
def _delete_object(self, container_name, object_name, atomic_action=True,
**kwargs):
"""Delete object from container.
:param container_name: str, name of the container to delete object from
:param object_name: str, name of the object to delete
:param atomic_action: bool, enable delete object to be tracked as an
atomic action
:param kwargs: dict, other optional parameters to delete_object
"""
if atomic_action:
with base.AtomicAction(self, "swift.delete_object"):
self.clients("swift").delete_object(container_name,
object_name, **kwargs)
else:
self.clients("swift").delete_object(container_name, object_name,
**kwargs)

View File

@ -134,12 +134,13 @@ class Clients(object):
def _get_auth_info(self, user_key="username",
password_key="password",
auth_url_key="auth_url",
project_name_key="project_id"
):
kw = {
user_key: self.endpoint.username,
password_key: self.endpoint.password,
"auth_url": self.endpoint.auth_url
auth_url_key: self.endpoint.auth_url
}
if project_name_key:
kw.update({project_name_key: self.endpoint.tenant_name})
@ -389,6 +390,7 @@ class Clients(object):
**self._get_auth_info(
user_key="user",
password_key="key",
auth_url_key="authurl",
project_name_key="tenant_name")
)
return client

View File

@ -0,0 +1,24 @@
{
"SwiftObjects.create_container_and_object_then_delete_all": [
{
"args": {
"objects_per_container": 5,
"object_size": 102400
},
"runner": {
"type": "constant",
"times": 4,
"concurrency": 2
},
"context": {
"users": {
"tenants": 1,
"users_per_tenant": 1
},
"roles": [
"admin"
]
}
}
]
}

View File

@ -0,0 +1,16 @@
---
SwiftObjects.create_container_and_object_then_delete_all:
-
args:
objects_per_container: 5
object_size: 102400
runner:
type: "constant"
times: 4
concurrency: 2
context:
users:
tenants: 1
users_per_tenant: 1
roles:
- "admin"

View File

@ -0,0 +1,24 @@
{
"SwiftObjects.create_container_and_object_then_download_object": [
{
"args": {
"objects_per_container": 5,
"object_size": 1024
},
"runner": {
"type": "constant",
"times": 6,
"concurrency": 3
},
"context": {
"users": {
"tenants": 1,
"users_per_tenant": 1
},
"roles": [
"admin"
]
}
}
]
}

View File

@ -0,0 +1,16 @@
---
SwiftObjects.create_container_and_object_then_download_object:
-
args:
objects_per_container: 5
object_size: 1024
runner:
type: "constant"
times: 6
concurrency: 3
context:
users:
tenants: 1
users_per_tenant: 1
roles:
- "admin"

View File

@ -0,0 +1,24 @@
{
"SwiftObjects.create_container_and_object_then_list_objects": [
{
"args": {
"objects_per_container": 2,
"object_size": 5120
},
"runner": {
"type": "constant",
"times": 2,
"concurrency": 2
},
"context": {
"users": {
"tenants": 1,
"users_per_tenant": 1
},
"roles": [
"admin"
]
}
}
]
}

View File

@ -0,0 +1,16 @@
---
SwiftObjects.create_container_and_object_then_list_objects:
-
args:
objects_per_container: 2
object_size: 5120
runner:
type: "constant"
times: 2
concurrency: 2
context:
users:
tenants: 1
users_per_tenant: 1
roles:
- "admin"

View File

@ -342,3 +342,55 @@ class KeystoneMixinTestCase(test.TestCase):
self.assertSequenceEqual(result[:2], keystone_mixin.list())
mock_wrap().list_some_resource2s.assert_called_once_with()
class SwiftMixinTestCase(test.TestCase):
def get_swift_mixin(self):
swift_mixin = resources.SwiftMixin()
swift_mixin._service = "swift"
return swift_mixin
def test_manager(self):
swift_mixin = self.get_swift_mixin()
swift_mixin.user = mock.MagicMock()
self.assertEqual(swift_mixin.user.swift.return_value,
swift_mixin._manager())
def test_id(self):
swift_mixin = self.get_swift_mixin()
swift_mixin.raw_resource = mock.MagicMock()
self.assertEqual(swift_mixin.raw_resource, swift_mixin.id())
def test_delete(self):
swift_mixin = self.get_swift_mixin()
swift_mixin.user = mock.MagicMock()
swift_mixin._resource = "some_resource"
swift_mixin.raw_resource = mock.MagicMock()
swift_mixin.delete()
swift_mixin.user.swift().delete_some_resource.assert_called_once_with(
*swift_mixin.raw_resource)
class SwiftObjectTestCase(test.TestCase):
@mock.patch("%s.SwiftMixin._manager" % BASE)
def test_list(self, mock_manager):
containers = [mock.MagicMock(), mock.MagicMock()]
objects = [mock.MagicMock(), mock.MagicMock(), mock.MagicMock()]
mock_manager().get_account.return_value = ("header", containers)
mock_manager().get_container.return_value = ("header", objects)
self.assertEqual(len(containers),
len(resources.SwiftContainer().list()))
self.assertEqual(len(containers) * len(objects),
len(resources.SwiftObject().list()))
class SwiftContainerTestCase(test.TestCase):
@mock.patch("%s.SwiftMixin._manager" % BASE)
def test_list(self, mock_manager):
containers = [mock.MagicMock(), mock.MagicMock(), mock.MagicMock()]
mock_manager().get_account.return_value = ("header", containers)
self.assertEqual(len(containers),
len(resources.SwiftContainer().list()))

View File

@ -0,0 +1,144 @@
# Copyright 2015 Cisco Systems, Inc.
# 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 mock
from rally.benchmark.scenarios.swift import objects
from tests.unit import fakes
from tests.unit import test
class SwiftObjectsTestCase(test.TestCase):
def test_create_container_and_object_then_list_objects(self):
scenario = objects.SwiftObjects()
scenario._create_container = mock.MagicMock(return_value="AA")
scenario._upload_object = mock.MagicMock()
scenario._list_objects = mock.MagicMock()
scenario.create_container_and_object_then_list_objects(
objects_per_container=5,
object_size=100)
self.assertEqual(1, scenario._create_container.call_count)
self.assertEqual(5, scenario._upload_object.call_count)
scenario._list_objects.assert_called_once_with("AA")
self._test_atomic_action_timer(scenario.atomic_actions(),
"swift.create_5_objects")
def test_create_container_and_object_then_delete_all(self):
scenario = objects.SwiftObjects()
scenario._create_container = mock.MagicMock(return_value="BB")
scenario._upload_object = mock.MagicMock(
side_effect=[("etaaag", "ooobj_%i" % i) for i in range(3)])
scenario._delete_object = mock.MagicMock()
scenario._delete_container = mock.MagicMock()
scenario.create_container_and_object_then_delete_all(
objects_per_container=3,
object_size=10)
self.assertEqual(1, scenario._create_container.call_count)
self.assertEqual(3, scenario._upload_object.call_count)
scenario._delete_object.assert_has_calls(
[mock.call("BB", "ooobj_%i" % i,
atomic_action=False) for i in range(3)])
scenario._delete_container.assert_called_once_with("BB")
self._test_atomic_action_timer(scenario.atomic_actions(),
"swift.create_3_objects")
self._test_atomic_action_timer(scenario.atomic_actions(),
"swift.delete_3_objects")
def test_create_container_and_object_then_download_object(self):
scenario = objects.SwiftObjects()
scenario._create_container = mock.MagicMock(return_value="CC")
scenario._upload_object = mock.MagicMock(
side_effect=[("etaaaag", "obbbj_%i" % i) for i in range(2)])
scenario._download_object = mock.MagicMock()
scenario.create_container_and_object_then_download_object(
objects_per_container=2,
object_size=50)
self.assertEqual(1, scenario._create_container.call_count)
self.assertEqual(2, scenario._upload_object.call_count)
scenario._download_object.assert_has_calls(
[mock.call("CC", "obbbj_%i" % i,
atomic_action=False) for i in range(2)])
self._test_atomic_action_timer(scenario.atomic_actions(),
"swift.create_2_objects")
self._test_atomic_action_timer(scenario.atomic_actions(),
"swift.download_2_objects")
def test_functional_create_container_and_object_then_list_objects(self):
names_list = ["AA", "BB", "CC", "DD"]
scenario = objects.SwiftObjects(clients=fakes.FakeClients())
scenario._generate_random_name = mock.MagicMock(side_effect=names_list)
scenario._list_objects = mock.MagicMock()
scenario.create_container_and_object_then_list_objects(
objects_per_container=3,
object_size=100)
scenario._list_objects.assert_called_once_with("AA")
self._test_atomic_action_timer(scenario.atomic_actions(),
"swift.create_3_objects")
def test_functional_create_container_and_object_then_delete_all(self):
names_list = ["111", "222", "333", "444", "555"]
scenario = objects.SwiftObjects(clients=fakes.FakeClients())
scenario._generate_random_name = mock.MagicMock(side_effect=names_list)
scenario._delete_object = mock.MagicMock()
scenario._delete_container = mock.MagicMock()
scenario.create_container_and_object_then_delete_all(
objects_per_container=4,
object_size=240)
scenario._delete_object.assert_has_calls(
[mock.call("111", name,
atomic_action=False) for name in names_list[1:]])
scenario._delete_container.assert_called_once_with("111")
self._test_atomic_action_timer(scenario.atomic_actions(),
"swift.create_4_objects")
self._test_atomic_action_timer(scenario.atomic_actions(),
"swift.delete_4_objects")
def test_functional_create_container_and_object_then_download_object(self):
names_list = ["aaa", "bbb", "ccc", "ddd", "eee", "fff"]
scenario = objects.SwiftObjects(clients=fakes.FakeClients())
scenario._generate_random_name = mock.MagicMock(side_effect=names_list)
scenario._download_object = mock.MagicMock()
scenario.create_container_and_object_then_download_object(
objects_per_container=5,
object_size=750)
scenario._download_object.assert_has_calls(
[mock.call("aaa", name,
atomic_action=False) for name in names_list[1:]])
self._test_atomic_action_timer(scenario.atomic_actions(),
"swift.create_5_objects")
self._test_atomic_action_timer(scenario.atomic_actions(),
"swift.download_5_objects")

View File

@ -0,0 +1,202 @@
# Copyright 2015: Cisco Systems, Inc.
# 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 mock
from rally.benchmark.scenarios.swift import utils
from tests.unit import test
SWIFT_UTILS = "rally.benchmark.scenarios.swift.utils"
class SwiftScenarioTestCase(test.TestCase):
@mock.patch(SWIFT_UTILS + ".SwiftScenario.clients")
def test__list_containers(self, mock_clients):
headers_dict = mock.MagicMock()
containers_list = mock.MagicMock()
mock_clients("swift").get_account.return_value = (headers_dict,
containers_list)
scenario = utils.SwiftScenario()
self.assertEqual((headers_dict, containers_list),
scenario._list_containers(fargs="f"))
kw = {"full_listing": True, "fargs": "f"}
mock_clients("swift").get_account.assert_called_once_with(**kw)
self._test_atomic_action_timer(scenario.atomic_actions(),
"swift.list_containers")
@mock.patch(SWIFT_UTILS + ".SwiftScenario.clients")
def test__create_container(self, mock_clients):
container_name = mock.MagicMock()
scenario = utils.SwiftScenario()
# name + public=True + kw
self.assertEqual(container_name,
scenario._create_container(container_name,
public=True, fargs="f"))
kw = {"headers": {"X-Container-Read": ".r:*,.rlistings"}, "fargs": "f"}
mock_clients("swift").put_container.assert_called_once_with(
container_name,
**kw)
# name + public=True + additional header + kw
mock_clients("swift").put_container.reset_mock()
self.assertEqual(container_name,
scenario._create_container(container_name,
public=True,
headers={"X-fake-name":
"fake-value"},
fargs="f"))
kw = {"headers": {"X-Container-Read": ".r:*,.rlistings",
"X-fake-name": "fake-value"}, "fargs": "f"}
mock_clients("swift").put_container.assert_called_once_with(
container_name,
**kw)
# name + public=False + additional header + kw
mock_clients("swift").put_container.reset_mock()
self.assertEqual(container_name,
scenario._create_container(container_name,
public=False,
headers={"X-fake-name":
"fake-value"},
fargs="f"))
kw = {"headers": {"X-fake-name": "fake-value"}, "fargs": "f"}
mock_clients("swift").put_container.assert_called_once_with(
container_name,
**kw)
# name + kw
mock_clients("swift").put_container.reset_mock()
self.assertEqual(container_name,
scenario._create_container(container_name, fargs="f"))
kw = {"fargs": "f"}
mock_clients("swift").put_container.assert_called_once_with(
container_name,
**kw)
# kw
scenario._generate_random_name = mock.MagicMock(
return_value=container_name)
mock_clients("swift").put_container.reset_mock()
self.assertEqual(container_name,
scenario._create_container(fargs="f"))
kw = {"fargs": "f"}
mock_clients("swift").put_container.assert_called_once_with(
container_name,
**kw)
self.assertEqual(1, scenario._generate_random_name.call_count)
self._test_atomic_action_timer(scenario.atomic_actions(),
"swift.create_container")
@mock.patch(SWIFT_UTILS + ".SwiftScenario.clients")
def test__delete_container(self, mock_clients):
container_name = mock.MagicMock()
scenario = utils.SwiftScenario()
scenario._delete_container(container_name, fargs="f")
kw = {"fargs": "f"}
mock_clients("swift").delete_container.assert_called_once_with(
container_name,
**kw)
self._test_atomic_action_timer(scenario.atomic_actions(),
"swift.delete_container")
@mock.patch(SWIFT_UTILS + ".SwiftScenario.clients")
def test__list_objects(self, mock_clients):
container_name = mock.MagicMock()
headers_dict = mock.MagicMock()
objects_list = mock.MagicMock()
mock_clients("swift").get_container.return_value = (headers_dict,
objects_list)
scenario = utils.SwiftScenario()
self.assertEqual((headers_dict, objects_list),
scenario._list_objects(container_name, fargs="f"))
kw = {"full_listing": True, "fargs": "f"}
mock_clients("swift").get_container.assert_called_once_with(
container_name,
**kw)
self._test_atomic_action_timer(scenario.atomic_actions(),
"swift.list_objects")
@mock.patch(SWIFT_UTILS + ".SwiftScenario.clients")
def test__upload_object(self, mock_clients):
container_name = mock.MagicMock()
object_name = mock.MagicMock()
content = mock.MagicMock()
etag = mock.MagicMock()
mock_clients("swift").put_object.return_value = etag
scenario = utils.SwiftScenario()
# container + content + name + kw
self.assertEqual((etag, object_name),
scenario._upload_object(container_name, content,
object_name=object_name,
fargs="f"))
kw = {"fargs": "f"}
mock_clients("swift").put_object.assert_called_once_with(
container_name, object_name,
content, **kw)
# container + content + kw
scenario._generate_random_name = mock.MagicMock(
return_value=object_name)
mock_clients("swift").put_object.reset_mock()
self.assertEqual((etag, object_name),
scenario._upload_object(container_name, content,
fargs="f"))
kw = {"fargs": "f"}
mock_clients("swift").put_object.assert_called_once_with(
container_name, object_name,
content, **kw)
self.assertEqual(1, scenario._generate_random_name.call_count)
self._test_atomic_action_timer(scenario.atomic_actions(),
"swift.upload_object")
@mock.patch(SWIFT_UTILS + ".SwiftScenario.clients")
def test__download_object(self, mock_clients):
container_name = mock.MagicMock()
object_name = mock.MagicMock()
headers_dict = mock.MagicMock()
content = mock.MagicMock()
mock_clients("swift").get_object.return_value = (headers_dict, content)
scenario = utils.SwiftScenario()
self.assertEqual((headers_dict, content),
scenario._download_object(container_name, object_name,
fargs="f"))
kw = {"fargs": "f"}
mock_clients("swift").get_object.assert_called_once_with(
container_name, object_name,
**kw)
self._test_atomic_action_timer(scenario.atomic_actions(),
"swift.download_object")
@mock.patch(SWIFT_UTILS + ".SwiftScenario.clients")
def test__delete_object(self, mock_clients):
container_name = mock.MagicMock()
object_name = mock.MagicMock()
scenario = utils.SwiftScenario()
scenario._delete_object(container_name, object_name, fargs="f")
kw = {"fargs": "f"}
mock_clients("swift").delete_object.assert_called_once_with(
container_name, object_name,
**kw)
self._test_atomic_action_timer(scenario.atomic_actions(),
"swift.delete_object")

View File

@ -900,7 +900,7 @@ class FakeObjectManager(FakeManager):
def put_object(self, container_name, object_name, content, **kwargs):
container = self.find(name=container_name)
if container is None or object_name in container.items:
if container is None:
raise swift_exceptions.ClientException("Object PUT failed")
container.items[object_name] = content
return mock.MagicMock()

View File

@ -403,7 +403,7 @@ class OSClientsTestCase(test.TestCase):
"user": self.endpoint.username,
"key": self.endpoint.password,
"tenant_name": self.endpoint.tenant_name,
"auth_url": self.endpoint.auth_url
"authurl": self.endpoint.auth_url
}
mock_swift.client.Connection.assert_called_once_with(**kw)
self.assertEqual(self.clients.cache["swift"], fake_swift)