Start instances using fixed network when possible

Uses the fixed_network_name option to select which network
to boot test instances on.  This allows Tempest to be run
in environments where there are multiple networks available.

This problem does not apply to nova-network environments because
it will happily start instances with multiple networks attached,
so the behavior is left as before in that case.

Co-Authored-By: Ben Nemec <bnemec@redhat.com>
Co-Authored-By: Vincent Untz <vuntz@suse.com>
Co-Authored-By: git-harry <git-harry@live.co.uk>

Change-Id: Ib5b84b59e3d182d8b9cc83954537c32f3eb9e388
Closes-Bug: #1250866
This commit is contained in:
Rohan Kanade 2013-12-10 18:59:35 +05:30 committed by Andrea Frittoli (andreaf)
parent 171d05e97f
commit 9ce97dfa35
12 changed files with 149 additions and 23 deletions

View File

@ -16,6 +16,7 @@ from tempest_lib.common.utils import data_utils
from tempest_lib import decorators
from tempest.api.compute import base
from tempest.common import fixed_network
from tempest import test
@ -112,7 +113,10 @@ class ServersAdminTestJSON(base.BaseV2ComputeAdminTest):
name = data_utils.rand_name('server')
flavor = self.flavor_ref
image_id = self.image_ref
test_server = self.client.create_server(name, image_id, flavor)
network = self.get_tenant_network()
network_kwargs = fixed_network.set_networks_kwarg(network)
test_server = self.client.create_server(name, image_id, flavor,
**network_kwargs)
self.addCleanup(self.client.delete_server, test_server['id'])
self.client.wait_for_server_status(test_server['id'], 'ACTIVE')
server = self.client.get_server(test_server['id'])

View File

@ -22,6 +22,7 @@ from tempest_lib import exceptions as lib_exc
from tempest import clients
from tempest.common import credentials
from tempest.common import fixed_network
from tempest import config
from tempest import exceptions
import tempest.test
@ -212,6 +213,8 @@ class BaseComputeTest(tempest.test.BaseTestCase):
flavor = kwargs.get('flavor', cls.flavor_ref)
image_id = kwargs.get('image_id', cls.image_ref)
kwargs = fixed_network.set_networks_kwarg(
cls.get_tenant_network(), kwargs) or {}
body = cls.servers_client.create_server(
name, image_id, flavor, **kwargs)

View File

@ -13,13 +13,15 @@
# License for the specific language governing permissions and limitations
# under the License.
import time
from tempest_lib import exceptions as lib_exc
from tempest.api.compute import base
from tempest import config
from tempest import exceptions
from tempest import test
import time
CONF = config.CONF
@ -125,7 +127,14 @@ class AttachInterfacesTestJSON(base.BaseV2ComputeTest):
self.assertTrue(interface_count > 0)
self._check_interface(ifs[0])
try:
iface = self._test_create_interface(server)
except lib_exc.BadRequest as e:
msg = ('Multiple possible networks found, use a Network ID to be '
'more specific.')
if not CONF.compute.fixed_network_name and e.message == msg:
raise
else:
ifs.append(iface)
iface = self._test_create_interface_by_network_id(server, ifs)

View File

@ -19,6 +19,7 @@ from tempest_lib import exceptions as lib_exc
from tempest.api.compute import base
from tempest.api import utils
from tempest.common import fixed_network
from tempest import config
from tempest import test
@ -66,9 +67,13 @@ class ListServerFiltersTestJSON(base.BaseV2ComputeTest):
raise RuntimeError("Image %s (image_ref_alt) was not found!" %
cls.image_ref_alt)
network = cls.get_tenant_network()
cls.fixed_network_name = network['name']
network_kwargs = fixed_network.set_networks_kwarg(network)
cls.s1_name = data_utils.rand_name(cls.__name__ + '-instance')
cls.s1 = cls.create_test_server(name=cls.s1_name,
wait_until='ACTIVE')
wait_until='ACTIVE',
**network_kwargs)
cls.s2_name = data_utils.rand_name(cls.__name__ + '-instance')
cls.s2 = cls.create_test_server(name=cls.s2_name,
@ -80,12 +85,6 @@ class ListServerFiltersTestJSON(base.BaseV2ComputeTest):
flavor=cls.flavor_ref_alt,
wait_until='ACTIVE')
cls.fixed_network_name = CONF.compute.fixed_network_name
if CONF.service_available.neutron:
if hasattr(cls.isolated_creds, 'get_primary_network'):
network = cls.isolated_creds.get_primary_network()
cls.fixed_network_name = network['name']
@test.idempotent_id('05e8a8e7-9659-459a-989d-92c2f501f4ba')
@utils.skip_unless_attr('multiple_images', 'Only one image found')
@test.attr(type='gate')

View File

@ -18,6 +18,7 @@ from tempest_lib.common.utils import data_utils
from tempest_lib import exceptions as lib_exc
from tempest import clients
from tempest.common import fixed_network
from tempest import config
from tempest import exceptions
import tempest.test
@ -62,6 +63,7 @@ class BaseVolumeTest(tempest.test.BaseTestCase):
super(BaseVolumeTest, cls).setup_clients()
cls.servers_client = cls.os.servers_client
cls.networks_client = cls.os.networks_client
if cls._api_version == 1:
cls.snapshots_client = cls.os.snapshots_client
@ -159,6 +161,15 @@ class BaseVolumeTest(tempest.test.BaseTestCase):
except Exception:
pass
@classmethod
def create_server(cls, name, **kwargs):
network = cls.get_tenant_network()
network_kwargs = fixed_network.set_networks_kwarg(network, kwargs)
return cls.servers_client.create_server(name,
cls.image_ref,
cls.flavor_ref,
**network_kwargs)
class BaseVolumeAdminTest(BaseVolumeTest):
"""Base test case class for all Volume Admin API tests."""

View File

@ -36,9 +36,7 @@ class VolumesV2ActionsTest(base.BaseVolumeTest):
# Create a test shared instance
srv_name = data_utils.rand_name(cls.__name__ + '-Instance')
cls.server = cls.servers_client.create_server(srv_name,
cls.image_ref,
cls.flavor_ref)
cls.server = cls.create_server(srv_name)
cls.servers_client.wait_for_server_status(cls.server['id'], 'ACTIVE')
# Create a test shared volume for attach/detach tests

View File

@ -179,9 +179,7 @@ class VolumesV2NegativeTest(base.BaseVolumeTest):
@test.services('compute')
def test_attach_volumes_with_nonexistent_volume_id(self):
srv_name = data_utils.rand_name('Instance')
server = self.servers_client.create_server(srv_name,
self.image_ref,
self.flavor_ref)
server = self.create_server(srv_name)
self.addCleanup(self.servers_client.delete_server, server['id'])
self.servers_client.wait_for_server_status(server['id'], 'ACTIVE')
self.assertRaises(lib_exc.NotFound,

View File

@ -69,9 +69,7 @@ class VolumesV2SnapshotTestJSON(base.BaseVolumeTest):
# Create a snapshot when volume status is in-use
# Create a test instance
server_name = data_utils.rand_name('instance')
server = self.servers_client.create_server(server_name,
self.image_ref,
self.flavor_ref)
server = self.create_server(server_name)
self.addCleanup(self.servers_client.delete_server, server['id'])
self.servers_client.wait_for_server_status(server['id'], 'ACTIVE')
mountpoint = '/dev/%s' % CONF.compute.volume_device_name

View File

@ -0,0 +1,83 @@
# 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 copy
from oslo_log import log as logging
from tempest_lib import exceptions as lib_exc
from tempest import config
CONF = config.CONF
LOG = logging.getLogger(__name__)
def get_tenant_network(creds_provider, compute_networks_client):
"""Get a network usable by the primary tenant
:param creds_provider: instance of credential provider
:param compute_networks_client: compute network client. We want to have the
compute network client so we can have use a common approach for both
neutron and nova-network cases. If this is not an admin network
client, set_network_kwargs might fail in case fixed_network_name
is the network to be used, and it's not visible to the tenant
:return a dict with 'id' and 'name' of the network
"""
fixed_network_name = CONF.compute.fixed_network_name
# NOTE(andreaf) get_primary_network will always be available once
# bp test-accounts-continued is implemented
if (CONF.auth.allow_tenant_isolation and
(CONF.service_available.neutron and
not CONF.service_available.ironic)):
network = creds_provider.get_primary_network()
else:
if fixed_network_name:
try:
resp = compute_networks_client.list_networks(
name=fixed_network_name)
if isinstance(resp, list):
networks = resp
elif isinstance(resp, dict):
networks = resp['networks']
else:
raise lib_exc.NotFound()
network = networks[0]
# To be consistent with network isolation, add name is only
# label is available
network['name'] = network.get('name', network.get('label'))
except lib_exc.NotFound:
# In case of nova network, if the fixed_network_name is not
# owned by the tenant, and the network client is not an admin
# one, list_networks will not find it
LOG.info('Unable to find network %s. '
'Starting instance without specifying a network.' %
fixed_network_name)
network = {'name': fixed_network_name}
LOG.info('Found network %s available for tenant' % network)
return network
def set_networks_kwarg(network, kwargs=None):
"""Set 'networks' kwargs for a server create if missing
:param network: dict of network to be used with 'id' and 'name'
:param kwargs: server create kwargs to be enhanced
:return: new dict of kwargs updated to include networks
"""
params = copy.copy(kwargs) or {}
if kwargs and 'networks' in kwargs:
return params
if network:
params.update({"networks": [{'uuid': network['id']}]})
return params

View File

@ -24,6 +24,7 @@ from tempest_lib import exceptions as lib_exc
from tempest import clients
from tempest.common import credentials
from tempest.common import fixed_network
from tempest.common.utils.linux import remote_client
from tempest import config
from tempest import exceptions
@ -184,6 +185,8 @@ class ScenarioTest(tempest.test.BaseTestCase):
flavor = CONF.compute.flavor_ref
if create_kwargs is None:
create_kwargs = {}
network = self.get_tenant_network()
fixed_network.set_networks_kwarg(network, create_kwargs)
LOG.debug("Creating a server (name: %s, image: %s, flavor: %s)",
name, image, flavor)

View File

@ -20,11 +20,15 @@ from tempest.common import service_client
class NetworksClientJSON(service_client.ServiceClient):
def list_networks(self):
def list_networks(self, name=None):
resp, body = self.get("os-networks")
body = json.loads(body)
self.expected_success(200, resp.status)
return service_client.ResponseBodyList(resp, body['networks'])
if name:
networks = [n for n in body['networks'] if n['label'] == name]
else:
networks = body['networks']
return service_client.ResponseBodyList(resp, networks)
def get_network(self, network_id):
resp, body = self.get("os-networks/%s" % str(network_id))

View File

@ -32,6 +32,7 @@ import testtools
from tempest import clients
from tempest.common import credentials
from tempest.common import fixed_network
import tempest.common.generator.valid_generator as valid
from tempest import config
from tempest import exceptions
@ -435,6 +436,21 @@ class BaseTestCase(testtools.testcase.WithAttributes,
'subnet': subnet,
'dhcp': dhcp}
@classmethod
def get_tenant_network(cls):
"""Get the network to be used in testing
:return: network dict including 'id' and 'name'
"""
# Make sure isolated_creds exists and get a network client
networks_client = cls.get_client_manager().networks_client
isolated_creds = getattr(cls, 'isolated_creds', None)
if credentials.is_admin_available():
admin_creds = isolated_creds.get_admin_creds()
networks_client = clients.Manager(admin_creds).networks_client
return fixed_network.get_tenant_network(isolated_creds,
networks_client)
def assertEmpty(self, list, msg=None):
self.assertTrue(len(list) == 0, msg)