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:
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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)
|
||||
|
||||
53
rally/plugins/openstack/scenarios/nova/networks.py
Normal file
53
rally/plugins/openstack/scenarios/nova/networks.py
Normal 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)
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
20
samples/tasks/scenarios/nova/create-and-delete-network.json
Normal file
20
samples/tasks/scenarios/nova/create-and-delete-network.json
Normal 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
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
13
samples/tasks/scenarios/nova/create-and-delete-network.yaml
Normal file
13
samples/tasks/scenarios/nova/create-and-delete-network.yaml
Normal 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
|
||||
20
samples/tasks/scenarios/nova/create-and-list-networks.json
Normal file
20
samples/tasks/scenarios/nova/create-and-list-networks.json
Normal 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
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
13
samples/tasks/scenarios/nova/create-and-list-networks.yaml
Normal file
13
samples/tasks/scenarios/nova/create-and-list-networks.yaml
Normal 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
|
||||
@@ -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):
|
||||
|
||||
49
tests/unit/plugins/openstack/scenarios/nova/test_networks.py
Normal file
49
tests/unit/plugins/openstack/scenarios/nova/test_networks.py
Normal 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)
|
||||
@@ -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")
|
||||
|
||||
@@ -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):
|
||||
|
||||
Reference in New Issue
Block a user