Add create-flavor and flavor-access-list scenario
Benchmark create-flavor and flavor-access-list Nova API. blueprint extend-api-benchmark-in-nova-scenarios Change-Id: I870405aaaec727cfb3a0b460dcf60c6a7ca4b6d1
This commit is contained in:
parent
d46955cae3
commit
297fff010a
@ -984,3 +984,31 @@
|
|||||||
sla:
|
sla:
|
||||||
failure_rate:
|
failure_rate:
|
||||||
max: 0
|
max: 0
|
||||||
|
|
||||||
|
NovaFlavors.create_flavor:
|
||||||
|
-
|
||||||
|
args:
|
||||||
|
ram: 500
|
||||||
|
vcpus: 1
|
||||||
|
disk: 1
|
||||||
|
runner:
|
||||||
|
type: "constant"
|
||||||
|
times: 5
|
||||||
|
concurrency: 2
|
||||||
|
sla:
|
||||||
|
failure_rate:
|
||||||
|
max: 0
|
||||||
|
|
||||||
|
NovaFlavors.create_and_list_flavor_access:
|
||||||
|
-
|
||||||
|
args:
|
||||||
|
ram: 500
|
||||||
|
vcpus: 1
|
||||||
|
disk: 1
|
||||||
|
runner:
|
||||||
|
type: "constant"
|
||||||
|
times: 5
|
||||||
|
concurrency: 2
|
||||||
|
sla:
|
||||||
|
failure_rate:
|
||||||
|
max: 0
|
||||||
|
@ -137,6 +137,14 @@ class NovaQuotas(QuotaMixin, base.ResourceManager):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@base.resource("nova", "flavors", order=next(_nova_order),
|
||||||
|
admin_required=True, perform_for_admin_only=True)
|
||||||
|
class NovaFlavors(base.ResourceManager):
|
||||||
|
def list(self):
|
||||||
|
return [r for r in self._manager().list()
|
||||||
|
if utils.name_matches_object(r.name, nova_utils.NovaScenario)]
|
||||||
|
|
||||||
|
|
||||||
@base.resource("nova", "floating_ips_bulk", order=next(_nova_order),
|
@base.resource("nova", "floating_ips_bulk", order=next(_nova_order),
|
||||||
admin_required=True)
|
admin_required=True)
|
||||||
class NovaFloatingIpsBulk(SynchronizedDeletion, base.ResourceManager):
|
class NovaFloatingIpsBulk(SynchronizedDeletion, base.ResourceManager):
|
||||||
|
@ -13,11 +13,14 @@
|
|||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
|
from rally.common import logging
|
||||||
from rally import consts
|
from rally import consts
|
||||||
from rally.plugins.openstack import scenario
|
from rally.plugins.openstack import scenario
|
||||||
from rally.plugins.openstack.scenarios.nova import utils
|
from rally.plugins.openstack.scenarios.nova import utils
|
||||||
from rally.task import validation
|
from rally.task import validation
|
||||||
|
|
||||||
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class NovaFlavors(utils.NovaScenario):
|
class NovaFlavors(utils.NovaScenario):
|
||||||
"""Benchmark scenarios for Nova flavors."""
|
"""Benchmark scenarios for Nova flavors."""
|
||||||
@ -36,3 +39,36 @@ class NovaFlavors(utils.NovaScenario):
|
|||||||
:param kwargs: Optional additional arguments for flavor listing
|
:param kwargs: Optional additional arguments for flavor listing
|
||||||
"""
|
"""
|
||||||
self._list_flavors(detailed, **kwargs)
|
self._list_flavors(detailed, **kwargs)
|
||||||
|
|
||||||
|
@validation.required_services(consts.Service.NOVA)
|
||||||
|
@validation.required_openstack(admin=True)
|
||||||
|
@scenario.configure(context={"admin_cleanup": ["nova"]})
|
||||||
|
def create_and_list_flavor_access(self, ram, vcpus, disk, **kwargs):
|
||||||
|
"""Create a non-public flavor and list its access rules
|
||||||
|
|
||||||
|
:param ram: Memory in MB for the flavor
|
||||||
|
:param vcpus: Number of VCPUs for the flavor
|
||||||
|
:param disk: Size of local disk in GB
|
||||||
|
:param kwargs: Optional additional arguments for flavor creation
|
||||||
|
"""
|
||||||
|
# NOTE(pirsriva): access rules can be listed
|
||||||
|
# only for non-public flavors
|
||||||
|
if kwargs.get("is_public", False):
|
||||||
|
LOG.warn("is_public cannot be set to True for listing flavor "
|
||||||
|
"access rules. Setting is_public to False")
|
||||||
|
kwargs["is_public"] = False
|
||||||
|
flavor = self._create_flavor(ram, vcpus, disk, **kwargs)
|
||||||
|
self._list_flavor_access(flavor.id)
|
||||||
|
|
||||||
|
@validation.required_services(consts.Service.NOVA)
|
||||||
|
@validation.required_openstack(admin=True)
|
||||||
|
@scenario.configure(context={"admin_cleanup": ["nova"]})
|
||||||
|
def create_flavor(self, ram, vcpus, disk, **kwargs):
|
||||||
|
"""Create a flavor.
|
||||||
|
|
||||||
|
:param ram: Memory in MB for the flavor
|
||||||
|
:param vcpus: Number of VCPUs for the flavor
|
||||||
|
:param disk: Size of local disk in GB
|
||||||
|
:param kwargs: Optional additional arguments for flavor creation
|
||||||
|
"""
|
||||||
|
self._create_flavor(ram, vcpus, disk, **kwargs)
|
||||||
|
@ -948,3 +948,24 @@ class NovaScenario(scenario.OpenStackScenario):
|
|||||||
:param binary: List all nova services matching given binary
|
:param binary: List all nova services matching given binary
|
||||||
"""
|
"""
|
||||||
return self.admin_clients("nova").services.list(host, binary)
|
return self.admin_clients("nova").services.list(host, binary)
|
||||||
|
|
||||||
|
@atomic.action_timer("nova.create_flavor")
|
||||||
|
def _create_flavor(self, ram, vcpus, disk, **kwargs):
|
||||||
|
"""Create a flavor
|
||||||
|
|
||||||
|
:param ram: Memory in MB for the flavor
|
||||||
|
:param vcpus: Number of VCPUs for the flavor
|
||||||
|
:param disk: Size of local disk in GB
|
||||||
|
:param kwargs: Optional additional arguments for flavor creation
|
||||||
|
"""
|
||||||
|
name = self.generate_random_name()
|
||||||
|
return self.admin_clients("nova").flavors.create(name, ram, vcpus,
|
||||||
|
disk, **kwargs)
|
||||||
|
|
||||||
|
@atomic.action_timer("nova.list_flavor_access")
|
||||||
|
def _list_flavor_access(self, flavor):
|
||||||
|
"""List access-rules for non-public flavor.
|
||||||
|
|
||||||
|
:param flavor: List access rules for flavor instance or flavor ID
|
||||||
|
"""
|
||||||
|
return self.admin_clients("nova").flavor_access.list(flavor=flavor)
|
||||||
|
@ -0,0 +1,16 @@
|
|||||||
|
{
|
||||||
|
"NovaFlavors.create_and_list_flavor_access": [
|
||||||
|
{
|
||||||
|
"runner": {
|
||||||
|
"type": "constant",
|
||||||
|
"concurrency": 2,
|
||||||
|
"times": 10
|
||||||
|
},
|
||||||
|
"args": {
|
||||||
|
"ram": 500,
|
||||||
|
"vcpus" : 1,
|
||||||
|
"disk": 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
---
|
||||||
|
NovaFlavors.create_and_list_flavor_access:
|
||||||
|
-
|
||||||
|
args:
|
||||||
|
ram: 500
|
||||||
|
vcpus: 1
|
||||||
|
disk: 1
|
||||||
|
runner:
|
||||||
|
type: "constant"
|
||||||
|
times: 10
|
||||||
|
concurrency: 2
|
16
samples/tasks/scenarios/nova/create-flavor.json
Normal file
16
samples/tasks/scenarios/nova/create-flavor.json
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
{
|
||||||
|
"NovaFlavors.create_flavor": [
|
||||||
|
{
|
||||||
|
"runner": {
|
||||||
|
"type": "constant",
|
||||||
|
"concurrency": 2,
|
||||||
|
"times": 10
|
||||||
|
},
|
||||||
|
"args": {
|
||||||
|
"ram": 500,
|
||||||
|
"vcpus" : 1,
|
||||||
|
"disk": 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
11
samples/tasks/scenarios/nova/create-flavor.yaml
Normal file
11
samples/tasks/scenarios/nova/create-flavor.yaml
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
---
|
||||||
|
NovaFlavors.create_flavor:
|
||||||
|
-
|
||||||
|
args:
|
||||||
|
ram: 500
|
||||||
|
vcpus: 1
|
||||||
|
disk: 1
|
||||||
|
runner:
|
||||||
|
type: "constant"
|
||||||
|
times: 10
|
||||||
|
concurrency: 2
|
@ -21,6 +21,7 @@ from neutronclient.common import exceptions as neutron_exceptions
|
|||||||
from rally.common import utils
|
from rally.common import utils
|
||||||
from rally.plugins.openstack.cleanup import resources
|
from rally.plugins.openstack.cleanup import resources
|
||||||
from rally.plugins.openstack.scenarios.keystone import utils as kutils
|
from rally.plugins.openstack.scenarios.keystone import utils as kutils
|
||||||
|
from rally.plugins.openstack.scenarios.nova import utils as nutils
|
||||||
from tests.unit import test
|
from tests.unit import test
|
||||||
|
|
||||||
BASE = "rally.plugins.openstack.cleanup.resources"
|
BASE = "rally.plugins.openstack.cleanup.resources"
|
||||||
@ -116,6 +117,22 @@ class NovaFloatingIPsTestCase(test.TestCase):
|
|||||||
self.assertIsNone(fips.name())
|
self.assertIsNone(fips.name())
|
||||||
|
|
||||||
|
|
||||||
|
class NovaFlavorsTestCase(test.TestCase):
|
||||||
|
|
||||||
|
@mock.patch("%s.base.ResourceManager._manager" % BASE)
|
||||||
|
@mock.patch("rally.common.utils.name_matches_object")
|
||||||
|
def test_list(self, mock_name_matches_object,
|
||||||
|
mock_resource_manager__manager):
|
||||||
|
flavors = [mock.MagicMock(name="rally_foo1"),
|
||||||
|
mock.MagicMock(name="rally_foo2"),
|
||||||
|
mock.MagicMock(name="foo3")]
|
||||||
|
mock_name_matches_object.side_effect = [False, True, True]
|
||||||
|
mock_resource_manager__manager().list.return_value = flavors
|
||||||
|
self.assertEqual(flavors[1:], resources.NovaFlavors().list())
|
||||||
|
mock_name_matches_object.assert_has_calls(
|
||||||
|
[mock.call(r.name, nutils.NovaScenario) for r in flavors])
|
||||||
|
|
||||||
|
|
||||||
class NovaSecurityGroupTestCase(test.TestCase):
|
class NovaSecurityGroupTestCase(test.TestCase):
|
||||||
|
|
||||||
@mock.patch("%s.base.ResourceManager._manager" % BASE)
|
@mock.patch("%s.base.ResourceManager._manager" % BASE)
|
||||||
|
@ -13,12 +13,14 @@
|
|||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
|
import ddt
|
||||||
import mock
|
import mock
|
||||||
|
|
||||||
from rally.plugins.openstack.scenarios.nova import flavors
|
from rally.plugins.openstack.scenarios.nova import flavors
|
||||||
from tests.unit import test
|
from tests.unit import test
|
||||||
|
|
||||||
|
|
||||||
|
@ddt.ddt
|
||||||
class NovaFlavorsTestCase(test.TestCase):
|
class NovaFlavorsTestCase(test.TestCase):
|
||||||
|
|
||||||
def test_list_flavors(self):
|
def test_list_flavors(self):
|
||||||
@ -26,3 +28,29 @@ class NovaFlavorsTestCase(test.TestCase):
|
|||||||
scenario._list_flavors = mock.Mock()
|
scenario._list_flavors = mock.Mock()
|
||||||
scenario.list_flavors(detailed=True, fakearg="fakearg")
|
scenario.list_flavors(detailed=True, fakearg="fakearg")
|
||||||
scenario._list_flavors.assert_called_once_with(True, fakearg="fakearg")
|
scenario._list_flavors.assert_called_once_with(True, fakearg="fakearg")
|
||||||
|
|
||||||
|
@ddt.data({},
|
||||||
|
{"is_public": True},
|
||||||
|
{"is_public": False},
|
||||||
|
{"fakeargs": "fakeargs"},
|
||||||
|
{"is_public": False, "fakeargs": "fakeargs"})
|
||||||
|
@ddt.unpack
|
||||||
|
def test_create_and_list_flavor_access(self, **kwargs):
|
||||||
|
scenario = flavors.NovaFlavors()
|
||||||
|
scenario._create_flavor = mock.Mock()
|
||||||
|
scenario._list_flavor_access = mock.Mock()
|
||||||
|
scenario.create_and_list_flavor_access(ram=100, vcpus=1, disk=1,
|
||||||
|
**kwargs)
|
||||||
|
kwargs.pop("is_public", None)
|
||||||
|
scenario._create_flavor.assert_called_once_with(100, 1, 1,
|
||||||
|
is_public=False,
|
||||||
|
**kwargs)
|
||||||
|
scenario._list_flavor_access.assert_called_once_with(
|
||||||
|
scenario._create_flavor.return_value.id)
|
||||||
|
|
||||||
|
def test_create_flavor(self):
|
||||||
|
scenario = flavors.NovaFlavors()
|
||||||
|
scenario._create_flavor = mock.MagicMock()
|
||||||
|
scenario.create_flavor(ram=100, vcpus=1, disk=1, fakeargs="fakeargs")
|
||||||
|
scenario._create_flavor.assert_called_once_with(100, 1, 1,
|
||||||
|
fakeargs="fakeargs")
|
||||||
|
@ -943,3 +943,29 @@ class NovaScenarioTestCase(test.ScenarioTestCase):
|
|||||||
host, binary)
|
host, binary)
|
||||||
self._test_atomic_action_timer(nova_scenario.atomic_actions(),
|
self._test_atomic_action_timer(nova_scenario.atomic_actions(),
|
||||||
"nova.list_services")
|
"nova.list_services")
|
||||||
|
|
||||||
|
def test__list_flavor_access(self):
|
||||||
|
nova_scenario = utils.NovaScenario()
|
||||||
|
result = nova_scenario._list_flavor_access("foo_id")
|
||||||
|
self.assertEqual(
|
||||||
|
self.admin_clients("nova").flavor_access.list.return_value,
|
||||||
|
result)
|
||||||
|
self.admin_clients("nova").flavor_access.list.assert_called_once_with(
|
||||||
|
flavor="foo_id")
|
||||||
|
self._test_atomic_action_timer(nova_scenario.atomic_actions(),
|
||||||
|
"nova.list_flavor_access")
|
||||||
|
|
||||||
|
def test__create_flavor(self):
|
||||||
|
nova_scenario = utils.NovaScenario()
|
||||||
|
random_name = "random_name"
|
||||||
|
nova_scenario.generate_random_name = mock.Mock(
|
||||||
|
return_value=random_name)
|
||||||
|
result = nova_scenario._create_flavor(500, 1, 1,
|
||||||
|
fakearg="fakearg")
|
||||||
|
self.assertEqual(
|
||||||
|
self.admin_clients("nova").flavors.create.return_value,
|
||||||
|
result)
|
||||||
|
self.admin_clients("nova").flavors.create.assert_called_once_with(
|
||||||
|
random_name, 500, 1, 1, fakearg="fakearg")
|
||||||
|
self._test_atomic_action_timer(nova_scenario.atomic_actions(),
|
||||||
|
"nova.create_flavor")
|
||||||
|
Loading…
Reference in New Issue
Block a user