Merge "Block additionalProperties on Nova API tests"
diff --git a/tempest/api/compute/base.py b/tempest/api/compute/base.py
index 9aacfa5..a1f6f99 100644
--- a/tempest/api/compute/base.py
+++ b/tempest/api/compute/base.py
@@ -16,11 +16,10 @@
import time
from oslo_log import log as logging
-from oslo_utils import excutils
from tempest_lib.common.utils import data_utils
from tempest_lib import exceptions as lib_exc
-from tempest.common import fixed_network
+from tempest.common import compute
from tempest import config
from tempest import exceptions
import tempest.test
@@ -192,41 +191,21 @@
server_group_id)
@classmethod
- def create_test_server(cls, **kwargs):
- """Wrapper utility that returns a test server."""
- name = data_utils.rand_name(cls.__name__ + "-instance")
- if 'name' in kwargs:
- name = kwargs.pop('name')
- flavor = kwargs.get('flavor', cls.flavor_ref)
- image_id = kwargs.get('image_id', cls.image_ref)
+ def create_test_server(cls, validatable=False, **kwargs):
+ """Wrapper utility that returns a test server.
- kwargs = fixed_network.set_networks_kwarg(
- cls.get_tenant_network(), kwargs) or {}
- body = cls.servers_client.create_server(
- name, image_id, flavor, **kwargs)
-
- # handle the case of multiple servers
- servers = [body]
- if 'min_count' in kwargs or 'max_count' in kwargs:
- # Get servers created which name match with name param.
- b = cls.servers_client.list_servers()
- servers = [s for s in b['servers'] if s['name'].startswith(name)]
-
- if 'wait_until' in kwargs:
- for server in servers:
- try:
- cls.servers_client.wait_for_server_status(
- server['id'], kwargs['wait_until'])
- except Exception:
- with excutils.save_and_reraise_exception():
- if ('preserve_server_on_error' not in kwargs
- or kwargs['preserve_server_on_error'] is False):
- for server in servers:
- try:
- cls.servers_client.delete_server(
- server['id'])
- except Exception:
- pass
+ This wrapper utility calls the common create test server and
+ returns a test server. The purpose of this wrapper is to minimize
+ the impact on the code of the tests already using this
+ function.
+ """
+ tenant_network = cls.get_tenant_network()
+ body, servers = compute.create_test_server(
+ cls.os,
+ validatable,
+ validation_resources=cls.validation_resources,
+ tenant_network=tenant_network,
+ **kwargs)
cls.servers.extend(servers)
diff --git a/tempest/api/compute/servers/test_create_server.py b/tempest/api/compute/servers/test_create_server.py
index 16b1597..408d4ee 100644
--- a/tempest/api/compute/servers/test_create_server.py
+++ b/tempest/api/compute/servers/test_create_server.py
@@ -53,14 +53,16 @@
personality = [{'path': '/test.txt',
'contents': base64.b64encode(file_contents)}]
disk_config = cls.disk_config
- cls.server_initial = cls.create_test_server(name=cls.name,
- meta=cls.meta,
- accessIPv4=cls.accessIPv4,
- accessIPv6=cls.accessIPv6,
- personality=personality,
- disk_config=disk_config)
+ cls.server_initial = cls.create_test_server(
+ validatable=True,
+ wait_until='ACTIVE',
+ name=cls.name,
+ meta=cls.meta,
+ accessIPv4=cls.accessIPv4,
+ accessIPv6=cls.accessIPv6,
+ personality=personality,
+ disk_config=disk_config)
cls.password = cls.server_initial['adminPass']
- cls.client.wait_for_server_status(cls.server_initial['id'], 'ACTIVE')
cls.server = cls.client.get_server(cls.server_initial['id'])
@test.attr(type='smoke')
diff --git a/tempest/common/compute.py b/tempest/common/compute.py
new file mode 100644
index 0000000..5de4b0e
--- /dev/null
+++ b/tempest/common/compute.py
@@ -0,0 +1,124 @@
+# Copyright (c) 2015 Hewlett-Packard Development Company, L.P.
+# 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 oslo_log import log as logging
+from oslo_utils import excutils
+from tempest_lib.common.utils import data_utils
+
+from tempest.common import fixed_network
+from tempest import config
+
+CONF = config.CONF
+
+LOG = logging.getLogger(__name__)
+
+
+def create_test_server(clients, validatable, validation_resources=None,
+ tenant_network=None, **kwargs):
+ """Common wrapper utility returning a test server.
+
+ This method is a common wrapper returning a test server that can be
+ pingable or sshable.
+
+ :param clients: Client manager which provides Openstack Tempest clients.
+ :param validatable: Whether the server will be pingable or sshable.
+ :param validation_resources: Resources created for the connection to the
+ server. Include a keypair, a security group and an IP.
+ :returns a tuple
+ """
+
+ # TODO(jlanoux) add support of wait_until PINGABLE/SSHABLE
+
+ if 'name' in kwargs:
+ name = kwargs.pop('name')
+ else:
+ name = data_utils.rand_name(__name__ + "-instance")
+
+ flavor = kwargs.get('flavor', CONF.compute.flavor_ref)
+ image_id = kwargs.get('image_id', CONF.compute.image_ref)
+
+ kwargs = fixed_network.set_networks_kwarg(
+ tenant_network, kwargs) or {}
+
+ if CONF.validation.run_validation and validatable:
+ # As a first implementation, multiple pingable or sshable servers will
+ # not be supported
+ if 'min_count' in kwargs or 'max_count' in kwargs:
+ msg = ("Multiple pingable or sshable servers not supported at "
+ "this stage.")
+ raise ValueError(msg)
+
+ if 'security_groups' in kwargs:
+ kwargs['security_groups'].append(
+ {'name': validation_resources['security_group']['name']})
+ else:
+ try:
+ kwargs['security_groups'] = [
+ {'name': validation_resources['security_group']['name']}]
+ except KeyError:
+ LOG.debug("No security group provided.")
+
+ if 'key_name' not in kwargs:
+ try:
+ kwargs['key_name'] = validation_resources['keypair']['name']
+ except KeyError:
+ LOG.debug("No key provided.")
+
+ if CONF.validation.connect_method == 'floating':
+ if 'wait_until' not in kwargs:
+ kwargs['wait_until'] = 'ACTIVE'
+
+ body = clients.servers_client.create_server(name, image_id, flavor,
+ **kwargs)
+
+ # handle the case of multiple servers
+ servers = [body]
+ if 'min_count' in kwargs or 'max_count' in kwargs:
+ # Get servers created which name match with name param.
+ body_servers = clients.servers_client.list_servers()
+ servers = \
+ [s for s in body_servers['servers'] if s['name'].startswith(name)]
+
+ # The name of the method to associate a floating IP to as server is too
+ # long for PEP8 compliance so:
+ assoc = clients.floating_ips_client.associate_floating_ip_to_server
+
+ if 'wait_until' in kwargs:
+ for server in servers:
+ try:
+ clients.servers_client.wait_for_server_status(
+ server['id'], kwargs['wait_until'])
+
+ # Multiple validatable servers are not supported for now. Their
+ # creation will fail with the condition above (l.58).
+ if CONF.validation.run_validation and validatable:
+ if CONF.validation.connect_method == 'floating':
+ assoc(floating_ip=validation_resources[
+ 'floating_ip']['ip'],
+ server_id=servers[0]['id'])
+
+ except Exception:
+ with excutils.save_and_reraise_exception():
+ if ('preserve_server_on_error' not in kwargs
+ or kwargs['preserve_server_on_error'] is False):
+ for server in servers:
+ try:
+ clients.servers_client.delete_server(
+ server['id'])
+ except Exception:
+ LOG.exception('Deleting server %s failed'
+ % server['id'])
+
+ return body, servers