Add Nova network scenarios

Added base methods (create/delete) for nova network
and added scenario to rally jobs for functional test.

Change-Id: I8c1f11e0f84345e10423b2117fc88513ca206fe0
Co-Authored-By: Andrey Kurilin <akurilin@mirantis.com>
This commit is contained in:
Alexander Gubanov
2015-04-28 11:39:05 +03:00
parent 9cb0ca295c
commit 9b5e2bcd97
14 changed files with 305 additions and 9 deletions

View File

@@ -1041,3 +1041,35 @@
sla:
failure_rate:
max: 0
NovaNetworks.create_and_list_networks:
-
args:
start_cidr: "10.10.0.0/24"
runner:
type: "constant"
times: 5
concurrency: 2
context:
users:
tenants: 3
users_per_tenant: 2
sla:
failure_rate:
max: 0
NovaNetworks.create_and_delete_network:
-
args:
start_cidr: "10.10.0.0/24"
runner:
type: "constant"
times: 5
concurrency: 2
context:
users:
tenants: 3
users_per_tenant: 2
sla:
failure_rate:
max: 0

View File

@@ -86,6 +86,7 @@ class _Service(utils.ImmutableMixin, utils.EnumMixin):
"""OpenStack services names, by rally convention."""
NOVA = "nova"
NOVA_NET = "nova-network"
NOVAV21 = "novav21"
NOVAV3 = "novav3"
CINDER = "cinder"

View File

@@ -98,6 +98,15 @@ class NovaFloatingIpsBulk(SynchronizedDeletion, base.ResourceManager):
if floating_ip.pool.startswith("rally_fip_pool_")]
@base.resource("nova", "networks", order=next(_nova_order),
admin_required=True)
class NovaNetworks(SynchronizedDeletion, base.ResourceManager):
def list(self):
return [net for net in self._manager().list()
if net.label.startswith("rally_novanet")]
# EC2
_ec2_order = get_order(250)

View File

@@ -0,0 +1,53 @@
# Copyright 2015: Mirantis 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 import consts
from rally.plugins.openstack.scenarios.nova import utils
from rally.task.scenarios import base
from rally.task import validation
class NovaNetworks(utils.NovaScenario):
"""Benchmark scenarios for Nova networks."""
@validation.restricted_parameters("label")
@validation.required_parameters("start_cidr")
@validation.required_services(consts.Service.NOVA, consts.Service.NOVA_NET)
@validation.required_openstack(admin=True)
@base.scenario(context={"admin_cleanup": ["nova.networks"]})
def create_and_list_networks(self, start_cidr, **kwargs):
"""Create nova network and list all networks.
:param start_cidr: IP range
:param kwargs: Optional additional arguments for network creation
"""
self._create_network(start_cidr, **kwargs)
self._list_networks()
@validation.restricted_parameters("label")
@validation.required_parameters("start_cidr")
@validation.required_services(consts.Service.NOVA, consts.Service.NOVA_NET)
@validation.required_openstack(admin=True)
@base.scenario(context={"admin_cleanup": ["nova.networks"]})
def create_and_delete_network(self, start_cidr, **kwargs):
"""Create nova network and delete it.
:param start_cidr: IP range
:param kwargs: Optional additional arguments for network creation
"""
net_id = self._create_network(start_cidr, **kwargs)
self._delete_network(net_id)

View File

@@ -798,3 +798,22 @@ class NovaScenario(scenario.OpenStackScenario):
:param server: Server to unlock
"""
server.unlock()
@base.atomic_action_timer("nova.create_network")
def _create_network(self, ip_range, **kwargs):
"""Create nova network.
:param ip_range: IP range in CIDR notation to create
"""
net_label = self._generate_random_name(prefix="rally_novanet")
ip_range = network_wrapper.generate_cidr(start_cidr=ip_range)
return self.admin_clients("nova").networks.create(
label=net_label, cidr=ip_range, **kwargs)
@base.atomic_action_timer("nova.delete_network")
def _delete_network(self, net_id):
"""Delete nova network.
:param net_id: The nova-network ID to delete
"""
return self.admin_clients("nova").networks.delete(net_id)

View File

@@ -476,7 +476,16 @@ def required_services(config, clients, deployment, *required_services):
:param *required_services: list of services names
"""
available_services = clients.services().values()
available_services = list(clients.services().values())
if consts.Service.NOVA_NET in required_services:
nova = osclients.Clients(
objects.Endpoint(**deployment["admin"])).nova()
for service in nova.services.list():
if (service.binary == consts.Service.NOVA_NET and
service.status == "enabled"):
available_services.append(consts.Service.NOVA_NET)
for service in required_services:
if service not in consts.Service:
return ValidationResult(False, _("Unknown service: %s") % service)

View File

@@ -0,0 +1,20 @@
{
"NovaNetworks.create_and_delete_network": [
{
"args": {
"start_cidr": "10.10.0.0/24"
},
"runner": {
"type": "constant",
"times": 5,
"concurrency": 2
},
"context": {
"users": {
"tenants": 3,
"users_per_tenant": 2
}
}
}
]
}

View File

@@ -0,0 +1,13 @@
---
NovaNetworks.create_and_delete_network:
-
args:
start_cidr: "10.10.0.0/24"
runner:
type: "constant"
times: 5
concurrency: 2
context:
users:
tenants: 3
users_per_tenant: 2

View File

@@ -0,0 +1,20 @@
{
"NovaNetworks.create_and_list_networks": [
{
"args": {
"start_cidr": "10.10.0.0/24"
},
"runner": {
"type": "constant",
"times": 5,
"concurrency": 2
},
"context": {
"users": {
"tenants": 3,
"users_per_tenant": 2
}
}
}
]
}

View File

@@ -0,0 +1,13 @@
---
NovaNetworks.create_and_list_networks:
-
args:
start_cidr: "10.10.0.0/24"
runner:
type: "constant"
times: 5
concurrency: 2
context:
users:
tenants: 3
users_per_tenant: 2

View File

@@ -137,6 +137,18 @@ class NovaFloatingIpsBulkTestCase(test.TestCase):
self.assertEqual(ip_range[1:], resources.NovaFloatingIpsBulk().list())
class NovaNetworksTestCase(test.TestCase):
@mock.patch("%s.base.ResourceManager._manager" % BASE)
def test_list(self, mock_resource_manager__manager):
network = [mock.Mock(label="a"), mock.Mock(label="rally_novanet_a"),
mock.Mock(label="rally_novanet_b")]
mock_resource_manager__manager.return_value.list.return_value = network
self.assertEqual(network[1:], resources.NovaNetworks().list())
mock_resource_manager__manager().list.assert_called_once_with()
class EC2MixinTestCase(test.TestCase):
def get_ec2_mixin(self):

View File

@@ -0,0 +1,49 @@
# Copyright 2015: Mirantis 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.plugins.openstack.scenarios.nova import networks
from tests.unit import test
class NovaNetworksTestCase(test.TestCase):
def test_create_and_list_networks(self):
scenario = networks.NovaNetworks()
scenario._create_network = mock.MagicMock()
scenario._list_networks = mock.MagicMock()
start_cidr = "10.2.0.0/24"
scenario.create_and_list_networks(start_cidr=start_cidr,
fakearg="fakearg")
scenario._create_network.assert_called_once_with(
start_cidr, fakearg="fakearg")
scenario._list_networks.assert_called_once_with()
def test_create_and_delete_network(self):
scenario = networks.NovaNetworks()
fake_network = mock.MagicMock()
fake_network.cidr = "10.2.0.0/24"
start_cidr = "10.2.0.0/24"
scenario._create_network = mock.MagicMock(return_value=fake_network)
scenario._delete_network = mock.MagicMock()
scenario.create_and_delete_network(start_cidr=start_cidr,
fakearg="fakearg")
scenario._create_network.assert_called_once_with(
start_cidr, fakearg="fakearg")
scenario._delete_network.assert_called_once_with(
fake_network)

View File

@@ -796,3 +796,33 @@ class NovaScenarioTestCase(test.ScenarioTestCase):
server.unlock.assert_called_once_with()
self._test_atomic_action_timer(nova_scenario.atomic_actions(),
"nova.unlock_server")
def test__delete_network(self):
fake_netlabel = "test1"
nova_scenario = utils.NovaScenario()
nova_scenario._delete_network(fake_netlabel)
self.admin_clients("nova").networks.delete.assert_called_once_with(
fake_netlabel)
self._test_atomic_action_timer(nova_scenario.atomic_actions(),
"nova.delete_network")
@mock.patch(NOVA_UTILS + ".network_wrapper.generate_cidr")
def test__create_network(self, mock_generate_cidr):
fake_cidr = "10.2.0.0/24"
fake_net = mock.MagicMock()
fake_net.cidr = fake_cidr
self.admin_clients("nova").networks.create.return_value = (fake_net)
nova_scenario = utils.NovaScenario()
nova_scenario._generate_random_name = mock.Mock(
return_value="rally_novanet_fake")
return_netlabel = nova_scenario._create_network(fake_cidr,
fakearg="fakearg")
mock_generate_cidr.assert_called_once_with(start_cidr=fake_cidr)
self.admin_clients("nova").networks.create.assert_called_once_with(
label="rally_novanet_fake", cidr=mock_generate_cidr.return_value,
fakearg="fakearg")
self.assertEqual(return_netlabel, fake_net)
self._test_atomic_action_timer(nova_scenario.atomic_actions(),
"nova.create_network")

View File

@@ -616,18 +616,34 @@ class ValidatorsTestCase(test.TestCase):
result = validator({"args": {"a": 1, "c": 3}}, None, None)
self.assertFalse(result.is_valid, result.msg)
def test_required_service(self):
@mock.patch("rally.common.objects.Endpoint")
def test_required_service(self, mock_endpoint):
validator = self._unwrap_validator(validation.required_services,
consts.Service.KEYSTONE,
consts.Service.NOVA,
consts.Service.NOVA_NET)
clients = mock.MagicMock()
clients.services().values.return_value = [consts.Service.KEYSTONE,
consts.Service.NOVA,
consts.Service.NOVA_NET]
fake_service = mock.Mock(binary="nova-network", status="enabled")
with mock.patch("rally.osclients.Clients") as clients_cls:
nova_client = clients_cls.return_value.nova.return_value
nova_client.services.list.return_value = [fake_service]
result = validator({}, clients, {"admin": {"info": "admin"}})
clients_cls.assert_called_once_with(mock_endpoint.return_value)
mock_endpoint.assert_called_once_with(info="admin")
self.assertTrue(result.is_valid, result.msg)
validator = self._unwrap_validator(validation.required_services,
consts.Service.KEYSTONE,
consts.Service.NOVA)
clients = mock.MagicMock()
clients.services().values.return_value = [
consts.Service.KEYSTONE, consts.Service.NOVA]
result = validator({}, clients, None)
self.assertTrue(result.is_valid, result.msg)
clients.services().values.return_value = [consts.Service.KEYSTONE]
result = validator({}, clients, None)
with mock.patch("rally.osclients.Clients") as clients_cls:
result = validator({}, clients, None)
self.assertFalse(clients_cls.called)
self.assertFalse(result.is_valid, result.msg)
def test_required_service_wrong_service(self):