Merge "Remove hyphen from rand_name calls in thirdparty tests"
diff --git a/tempest/api/compute/admin/test_servers.py b/tempest/api/compute/admin/test_servers.py
index c872184..ef3a029 100644
--- a/tempest/api/compute/admin/test_servers.py
+++ b/tempest/api/compute/admin/test_servers.py
@@ -16,6 +16,7 @@
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 @@
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'])
diff --git a/tempest/api/compute/base.py b/tempest/api/compute/base.py
index ddfe6de..b794101 100644
--- a/tempest/api/compute/base.py
+++ b/tempest/api/compute/base.py
@@ -22,6 +22,7 @@
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 @@
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)
diff --git a/tempest/api/compute/servers/test_attach_interfaces.py b/tempest/api/compute/servers/test_attach_interfaces.py
index 0702f3f..42a61da 100644
--- a/tempest/api/compute/servers/test_attach_interfaces.py
+++ b/tempest/api/compute/servers/test_attach_interfaces.py
@@ -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,8 +127,15 @@
self.assertTrue(interface_count > 0)
self._check_interface(ifs[0])
- iface = self._test_create_interface(server)
- ifs.append(iface)
+ 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)
ifs.append(iface)
diff --git a/tempest/api/compute/servers/test_list_server_filters.py b/tempest/api/compute/servers/test_list_server_filters.py
index 5c10f30..70e4dff 100644
--- a/tempest/api/compute/servers/test_list_server_filters.py
+++ b/tempest/api/compute/servers/test_list_server_filters.py
@@ -19,6 +19,7 @@
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 @@
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 @@
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')
diff --git a/tempest/api/volume/base.py b/tempest/api/volume/base.py
index 157bd44..1f76b1c 100644
--- a/tempest/api/volume/base.py
+++ b/tempest/api/volume/base.py
@@ -18,6 +18,7 @@
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 @@
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 @@
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."""
diff --git a/tempest/api/volume/test_volumes_actions.py b/tempest/api/volume/test_volumes_actions.py
index 3de5021..1872ec7 100644
--- a/tempest/api/volume/test_volumes_actions.py
+++ b/tempest/api/volume/test_volumes_actions.py
@@ -36,9 +36,7 @@
# 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
diff --git a/tempest/api/volume/test_volumes_negative.py b/tempest/api/volume/test_volumes_negative.py
index af6e24e..a47e964 100644
--- a/tempest/api/volume/test_volumes_negative.py
+++ b/tempest/api/volume/test_volumes_negative.py
@@ -179,9 +179,7 @@
@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,
diff --git a/tempest/api/volume/test_volumes_snapshots.py b/tempest/api/volume/test_volumes_snapshots.py
index 2b6339a..b277390 100644
--- a/tempest/api/volume/test_volumes_snapshots.py
+++ b/tempest/api/volume/test_volumes_snapshots.py
@@ -69,9 +69,7 @@
# 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
diff --git a/tempest/common/fixed_network.py b/tempest/common/fixed_network.py
new file mode 100644
index 0000000..83822c2
--- /dev/null
+++ b/tempest/common/fixed_network.py
@@ -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
diff --git a/tempest/scenario/manager.py b/tempest/scenario/manager.py
index f8cc17c..bae8296 100644
--- a/tempest/scenario/manager.py
+++ b/tempest/scenario/manager.py
@@ -24,6 +24,7 @@
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 @@
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)
diff --git a/tempest/services/compute/json/networks_client.py b/tempest/services/compute/json/networks_client.py
index ef1c058..0ae0920 100644
--- a/tempest/services/compute/json/networks_client.py
+++ b/tempest/services/compute/json/networks_client.py
@@ -20,11 +20,15 @@
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))
diff --git a/tempest/test.py b/tempest/test.py
index 19bae74..da936b4 100644
--- a/tempest/test.py
+++ b/tempest/test.py
@@ -32,6 +32,7 @@
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 @@
'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)