Add nova.BootServerAndAttachInterface scenario

Create server and subnet, then attach the interface to it.

This scenario measures the "nova interface-attach" command.

Change-Id: I83ea0364ebdcac302ff162b926a838eb7dd1634d
This commit is contained in:
zhangzhang 2017-01-12 08:04:25 -05:00
parent e332eb1aea
commit e00a90e2a6
7 changed files with 193 additions and 0 deletions

View File

@ -1370,6 +1370,34 @@
failure_rate: failure_rate:
max: 0 max: 0
NovaServers.boot_server_and_attach_interface:
-
args:
flavor:
name: {{flavor_name}}
image:
name: {{image_name}}
network_create_args: {}
subnet_create_args: {}
subnet_cidr_start: "1.1.0.0/30"
boot_server_args: {}
runner:
type: "constant"
times: 5
concurrency: 2
context:
network: {}
users:
tenants: 2
users_per_tenant: 2
quotas:
neutron:
network: -1
subnet: -1
sla:
failure_rate:
max: 0
NovaAggregates.create_aggregate_add_host_and_boot_server: NovaAggregates.create_aggregate_add_host_and_boot_server:
- -
args: args:

View File

@ -20,6 +20,7 @@ from rally import consts
from rally import exceptions as rally_exceptions from rally import exceptions as rally_exceptions
from rally.plugins.openstack import scenario from rally.plugins.openstack import scenario
from rally.plugins.openstack.scenarios.cinder import utils as cinder_utils from rally.plugins.openstack.scenarios.cinder import utils as cinder_utils
from rally.plugins.openstack.scenarios.neutron import utils as neutron_utils
from rally.plugins.openstack.scenarios.nova import utils from rally.plugins.openstack.scenarios.nova import utils
from rally.plugins.openstack.wrappers import network as network_wrapper from rally.plugins.openstack.wrappers import network as network_wrapper
from rally.task import types from rally.task import types
@ -837,6 +838,38 @@ class BootAndAssociateFloatingIp(utils.NovaScenario,
self._associate_floating_ip(server, address["ip"]) self._associate_floating_ip(server, address["ip"])
@types.convert(image={"type": "glance_image"},
flavor={"type": "nova_flavor"})
@validation.image_valid_on_flavor("flavor", "image")
@validation.required_services(consts.Service.NOVA, consts.Service.NEUTRON)
@validation.add("required_platform", platform="openstack", users=True)
@scenario.configure(context={"cleanup": ["nova", "neutron"]},
name="NovaServers.boot_server_and_attach_interface")
class BootServerAndAttachInterface(utils.NovaScenario,
neutron_utils.NeutronScenario):
def run(self, image, flavor, network_create_args=None,
subnet_create_args=None, subnet_cidr_start=None,
boot_server_args=None):
"""Create server and subnet, then attach the interface to it.
This scenario measures the "nova interface-attach" command performance.
:param image: image to be used to boot an instance
:param flavor: flavor to be used to boot an instance
:param network_create_args: dict, POST /v2.0/networks request
options.
:param subnet_create_args: dict, POST /v2.0/subnets request options
:param subnet_cidr_start: str, start value for subnets CIDR
:param boot_server_args: Optional additional arguments for
server creation
"""
network = self._get_or_create_network(network_create_args)
self._create_subnet(network, subnet_create_args, subnet_cidr_start)
server = self._boot_server(image, flavor, **boot_server_args)
self._attach_interface(server, net_id=network["network"]["id"])
@types.convert(image={"type": "glance_image"}, @types.convert(image={"type": "glance_image"},
flavor={"type": "nova_flavor"}) flavor={"type": "nova_flavor"})
@validation.image_valid_on_flavor("flavor", "image") @validation.image_valid_on_flavor("flavor", "image")

View File

@ -1282,3 +1282,18 @@ class NovaScenario(scenario.OpenStackScenario):
""" """
return self.admin_clients("nova").aggregates.set_metadata(aggregate, return self.admin_clients("nova").aggregates.set_metadata(aggregate,
metadata) metadata)
@atomic.action_timer("nova.attach_interface")
def _attach_interface(self, server, port_id=None,
net_id=None, fixed_ip=None):
"""Attach a network_interface to an instance.
:param server: The :class:`Server` (or its ID) to attach to.
:param port_id: The port to attach.
:param network_id: the Network to attach
:param fixed_ip: the Fix_ip to attach
:returns the server that has attach interface
"""
return self.clients("nova").servers.interface_attach(server,
port_id, net_id,
fixed_ip)

View File

@ -0,0 +1,43 @@
{% set flavor_name = flavor_name or "m1.tiny" %}
{% set image_name = "^(cirros.*-disk|TestVM)$" %}
{
"NovaServers.boot_server_and_attach_interface": [
{
"args": {
"flavor": {
"name": "{{flavor_name}}"
},
"image": {
"name": "{{image_name}}"
},
"network_create_args": {},
"subnet_create_args": {},
"subnet_cidr_start": "1.1.0.0/30",
"boot_server_args": {}
},
"runner": {
"type": "constant",
"times": 5,
"concurrency": 2
},
"context": {
"network": {},
"users": {
"tenants": 2,
"users_per_tenant": 2
},
"quotas": {
"neutron": {
"network": -1,
"subnet": -1
}
}
},
"sla": {
"failure_rate": {
"max": 0
}
}
}
]
}

View File

@ -0,0 +1,30 @@
{% set flavor_name = flavor_name or "m1.tiny" %}
{% set image_name = "^(cirros.*-disk|TestVM)$" %}
---
NovaServers.boot_server_and_attach_interface:
-
args:
flavor:
name: "{{flavor_name}}"
image:
name: "{{image_name}}"
network_create_args: {}
subnet_create_args: {}
subnet_cidr_start: "1.1.0.0/30"
boot_server_args: {}
runner:
type: "constant"
times: 5
concurrency: 2
context:
network: {}
users:
tenants: 2
users_per_tenant: 2
quotas:
neutron:
network: -1
subnet: -1
sla:
failure_rate:
max: 0

View File

@ -847,6 +847,37 @@ class NovaServersTestCase(test.ScenarioTestCase):
scenario._update_server.assert_called_once_with( scenario._update_server.assert_called_once_with(
scenario._boot_server.return_value, "desp") scenario._boot_server.return_value, "desp")
def test_boot_server_and_attach_interface(self):
network_create_args = {"router:external": True}
subnet_create_args = {"allocation_pools": []}
subnet_cidr_start = "10.1.0.0/16"
boot_server_args = {}
net = mock.MagicMock()
subnet = mock.MagicMock()
server = mock.MagicMock()
scenario = servers.BootServerAndAttachInterface(self.context)
scenario._get_or_create_network = mock.Mock(return_value=net)
scenario._create_subnet = mock.Mock(return_value=subnet)
scenario._boot_server = mock.Mock(return_value=server)
scenario._attach_interface = mock.Mock()
scenario.run("image", "flavor",
network_create_args=network_create_args,
subnet_create_args=subnet_create_args,
subnet_cidr_start=subnet_cidr_start,
boot_server_args=boot_server_args)
scenario._get_or_create_network.assert_called_once_with(
network_create_args)
scenario._create_subnet.assert_called_once_with(net,
subnet_create_args,
subnet_cidr_start)
scenario._boot_server.assert_called_once_with("image", "flavor",
**boot_server_args)
scenario._attach_interface.assert_called_once_with(
server, net_id=net["network"]["id"])
def test_boot_server_from_volume_snapshot(self): def test_boot_server_from_volume_snapshot(self):
fake_volume = mock.MagicMock(id="volume_id") fake_volume = mock.MagicMock(id="volume_id")
fake_snapshot = mock.MagicMock(id="snapshot_id") fake_snapshot = mock.MagicMock(id="snapshot_id")

View File

@ -1278,6 +1278,19 @@ class NovaScenarioTestCase(test.ScenarioTestCase):
self._test_atomic_action_timer(nova_scenario.atomic_actions(), self._test_atomic_action_timer(nova_scenario.atomic_actions(),
"nova.uptime_hypervisor") "nova.uptime_hypervisor")
def test__attach_interface(self):
fake_server = mock.Mock()
nova_scenario = utils.NovaScenario()
result = nova_scenario._attach_interface(fake_server, net_id="id")
self.assertEqual(
self.clients("nova").servers.interface_attach.return_value,
result)
self.clients("nova").servers.interface_attach.assert_called_once_with(
fake_server, None, "id", None)
self._test_atomic_action_timer(nova_scenario.atomic_actions(),
"nova.attach_interface")
def test_aggregate_set_metadata(self): def test_aggregate_set_metadata(self):
nova_scenario = utils.NovaScenario(context=self.context) nova_scenario = utils.NovaScenario(context=self.context)
fake_metadata = {"test_metadata": "true"} fake_metadata = {"test_metadata": "true"}