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:
parent
171d05e97f
commit
9ce97dfa35
|
@ -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'])
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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')
|
||||
|
|
|
@ -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."""
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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)
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
Loading…
Reference in New Issue