Merge "Use skip_checks for live-migration feature in test"
diff --git a/tempest/api/compute/base.py b/tempest/api/compute/base.py
index ec2192f..b3f69c1 100644
--- a/tempest/api/compute/base.py
+++ b/tempest/api/compute/base.py
@@ -147,7 +147,7 @@
Method will delete the server when it's dirty.
The setUp method is responsible for creating a new server.
Exceptions raised in tearDown class are fails the test case,
- This method supposed to use only by tierDown methods, when
+ This method supposed to use only by tearDown methods, when
the shared server_id is stored in the server_id of the class.
"""
if getattr(cls, 'server_id', None) is not None:
diff --git a/tempest/api/compute/servers/test_server_actions.py b/tempest/api/compute/servers/test_server_actions.py
index a59cb16..0754d27 100644
--- a/tempest/api/compute/servers/test_server_actions.py
+++ b/tempest/api/compute/servers/test_server_actions.py
@@ -52,7 +52,7 @@
except Exception:
# Rebuild server if something happened to it during a test
self.__class__.server_id = self.rebuild_server(
- self.server_id, validatable=True)['server']
+ self.server_id, validatable=True)
def tearDown(self):
self.server_check_teardown()
diff --git a/tempest/api/identity/admin/v2/test_users.py b/tempest/api/identity/admin/v2/test_users.py
index 8146828..6341106 100644
--- a/tempest/api/identity/admin/v2/test_users.py
+++ b/tempest/api/identity/admin/v2/test_users.py
@@ -146,7 +146,7 @@
user_ids.append(user2['id'])
self.data.users.append(user2)
# List of users for the respective tenant ID
- body = (self.client.list_users_for_tenant(self.data.tenant['id'])
+ body = (self.client.list_tenant_users(self.data.tenant['id'])
['users'])
for i in body:
fetched_user_ids.append(i['id'])
@@ -182,7 +182,7 @@
second_user['id'],
role['id'])['role']
# List of users with roles for the respective tenant ID
- body = (self.client.list_users_for_tenant(self.data.tenant['id'])
+ body = (self.client.list_tenant_users(self.data.tenant['id'])
['users'])
for i in body:
fetched_user_ids.append(i['id'])
diff --git a/tempest/api/identity/admin/v2/test_users_negative.py b/tempest/api/identity/admin/v2/test_users_negative.py
index 6d9d84b..a88053d 100644
--- a/tempest/api/identity/admin/v2/test_users_negative.py
+++ b/tempest/api/identity/admin/v2/test_users_negative.py
@@ -247,4 +247,4 @@
# List the users with invalid tenant id
for invalid in invalid_id:
self.assertRaises(lib_exc.NotFound,
- self.client.list_users_for_tenant, invalid)
+ self.client.list_tenant_users, invalid)
diff --git a/tempest/config.py b/tempest/config.py
index 0cda018..26823de 100644
--- a/tempest/config.py
+++ b/tempest/config.py
@@ -255,6 +255,7 @@
"when sshing to a guest."),
cfg.StrOpt('ssh_auth_method',
default='keypair',
+ choices=('keypair', 'configured', 'adminpass', 'disabled'),
help="Auth method used for authenticate to the instance. "
"Valid choices are: keypair, configured, adminpass "
"and disabled. "
@@ -264,6 +265,7 @@
"Disabled: avoid using ssh when it is an option."),
cfg.StrOpt('ssh_connect_method',
default='floating',
+ choices=('fixed', 'floating'),
help="How to connect to the instance? "
"fixed: using the first ip belongs the fixed network "
"floating: creating and using a floating ip."),
@@ -330,7 +332,13 @@
help='Unallocated floating IP range, which will be used to '
'test the floating IP bulk feature for CRUD operation. '
'This block must not overlap an existing floating IP '
- 'pool.')
+ 'pool.'),
+ cfg.IntOpt('min_compute_nodes',
+ default=1,
+ help=('The minimum number of compute nodes expected. This will '
+ 'be utilized by some multinode specific tests to ensure '
+ 'that requests match the expected size of the cluster '
+ 'you are testing with.'))
]
compute_features_group = cfg.OptGroup(name='compute-feature-enabled',
diff --git a/tempest/scenario/test_baremetal_basic_ops.py b/tempest/scenario/test_baremetal_basic_ops.py
index c0b82b6..ed691ac 100644
--- a/tempest/scenario/test_baremetal_basic_ops.py
+++ b/tempest/scenario/test_baremetal_basic_ops.py
@@ -107,13 +107,6 @@
return None
return int(ephemeral)
- def add_floating_ip(self):
- floating_ip = (self.floating_ips_client.create_floating_ip()
- ['floating_ip'])
- self.floating_ips_client.associate_floating_ip_to_server(
- floating_ip['ip'], self.instance['id'])
- return floating_ip['ip']
-
def validate_ports(self):
for port in self.get_ports(self.node['uuid']):
n_port_id = port['extra']['vif_port_id']
@@ -131,7 +124,7 @@
self.validate_ports()
self.verify_connectivity()
if CONF.compute.ssh_connect_method == 'floating':
- floating_ip = self.add_floating_ip()
+ floating_ip = self.create_floating_ip(self.instance)['ip']
self.verify_connectivity(ip=floating_ip)
vm_client = self.get_remote_client(self.instance)
diff --git a/tempest/scenario/test_server_basic_ops.py b/tempest/scenario/test_server_basic_ops.py
index e2f8adb..c55cff6 100644
--- a/tempest/scenario/test_server_basic_ops.py
+++ b/tempest/scenario/test_server_basic_ops.py
@@ -89,17 +89,10 @@
def verify_ssh(self):
if self.run_ssh:
# Obtain a floating IP
- self.floating_ip = (self.floating_ips_client.create_floating_ip()
- ['floating_ip'])
- self.addCleanup(self.delete_wrapper,
- self.floating_ips_client.delete_floating_ip,
- self.floating_ip['id'])
- # Attach a floating IP
- self.floating_ips_client.associate_floating_ip_to_server(
- self.floating_ip['ip'], self.instance['id'])
+ self.fip = self.create_floating_ip(self.instance)['ip']
# Check ssh
self.ssh_client = self.get_remote_client(
- server_or_ip=self.floating_ip['ip'],
+ server_or_ip=self.fip,
username=self.image_utils.ssh_user(self.image_ref),
private_key=self.keypair['private_key'])
@@ -110,12 +103,11 @@
def exec_cmd_and_verify_output():
cmd = 'curl ' + md_url
- floating_ip = self.floating_ip['ip']
result = self.ssh_client.exec_command(cmd)
if result:
msg = ('Failed while verifying metadata on server. Result '
- 'of command "%s" is NOT "%s".' % (cmd, floating_ip))
- self.assertEqual(floating_ip, result, msg)
+ 'of command "%s" is NOT "%s".' % (cmd, self.fip))
+ self.assertEqual(self.fip, result, msg)
return 'Verification is successful!'
if not test.call_until_true(exec_cmd_and_verify_output,
diff --git a/tempest/scenario/test_server_multinode.py b/tempest/scenario/test_server_multinode.py
new file mode 100644
index 0000000..ef78b4a
--- /dev/null
+++ b/tempest/scenario/test_server_multinode.py
@@ -0,0 +1,88 @@
+# Copyright 2012 OpenStack Foundation
+# 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 tempest import config
+from tempest import exceptions
+from tempest.scenario import manager
+from tempest import test
+
+CONF = config.CONF
+
+LOG = logging.getLogger(__name__)
+
+
+class TestServerMultinode(manager.ScenarioTest):
+
+ """
+ This is a set of tests specific to multinode testing.
+
+ """
+ credentials = ['primary', 'admin']
+
+ @classmethod
+ def setup_clients(cls):
+ super(TestServerMultinode, cls).setup_clients()
+ # Use admin client by default
+ cls.manager = cls.admin_manager
+ # this is needed so that we can use the availability_zone:host
+ # scheduler hint, which is admin_only by default
+ cls.servers_client = cls.admin_manager.servers_client
+ super(TestServerMultinode, cls).resource_setup()
+
+ @test.idempotent_id('9cecbe35-b9d4-48da-a37e-7ce70aa43d30')
+ @test.attr(type='smoke')
+ @test.services('compute', 'network')
+ def test_schedule_to_all_nodes(self):
+ host_client = self.manager.hosts_client
+ hosts = host_client.list_hosts()['hosts']
+ hosts = [x for x in hosts if x['service'] == 'compute']
+
+ # ensure we have at least as many compute hosts as we expect
+ if len(hosts) < CONF.compute.min_compute_nodes:
+ raise exceptions.InvalidConfiguration(
+ "Host list %s is shorter than min_compute_nodes. "
+ "Did a compute worker not boot correctly?" % hosts)
+
+ # create 1 compute for each node, up to the min_compute_nodes
+ # threshold (so that things don't get crazy if you have 1000
+ # compute nodes but set min to 3).
+ servers = []
+
+ for host in hosts[:CONF.compute.min_compute_nodes]:
+ create_kwargs = {
+ 'availability_zone': '%(zone)s:%(host_name)s' % host
+ }
+
+ # by getting to active state here, this means this has
+ # landed on the host in question.
+ inst = self.create_server(image=CONF.compute.image_ref,
+ flavor=CONF.compute.flavor_ref,
+ create_kwargs=create_kwargs)
+ server = self.servers_client.show_server(inst['id'])['server']
+ servers.append(server)
+
+ # make sure we really have the number of servers we think we should
+ self.assertEqual(
+ len(servers), CONF.compute.min_compute_nodes,
+ "Incorrect number of servers built %s" % servers)
+
+ # ensure that every server ended up on a different host
+ host_ids = [x['hostId'] for x in servers]
+ self.assertEqual(
+ len(set(host_ids)), len(servers),
+ "Incorrect number of distinct host_ids scheduled to %s" % servers)
diff --git a/tempest/scenario/test_shelve_instance.py b/tempest/scenario/test_shelve_instance.py
index bc80412..3b38888 100644
--- a/tempest/scenario/test_shelve_instance.py
+++ b/tempest/scenario/test_shelve_instance.py
@@ -79,15 +79,9 @@
create_kwargs=create_kwargs)
if CONF.compute.use_floatingip_for_ssh:
- floating_ip = (self.floating_ips_client.create_floating_ip()
- ['floating_ip'])
- self.addCleanup(self.delete_wrapper,
- self.floating_ips_client.delete_floating_ip,
- floating_ip['id'])
- self.floating_ips_client.associate_floating_ip_to_server(
- floating_ip['ip'], server['id'])
+ floating_ip = self.create_floating_ip(server)['ip']
timestamp = self.create_timestamp(
- floating_ip['ip'], private_key=keypair['private_key'])
+ floating_ip, private_key=keypair['private_key'])
else:
timestamp = self.create_timestamp(
server, private_key=keypair['private_key'])
@@ -97,7 +91,7 @@
# with the instance snapshot
self._shelve_then_unshelve_server(server)
if CONF.compute.use_floatingip_for_ssh:
- timestamp2 = self.get_timestamp(floating_ip['ip'],
+ timestamp2 = self.get_timestamp(floating_ip,
private_key=keypair['private_key'])
else:
timestamp2 = self.get_timestamp(server,
diff --git a/tempest/services/identity/v2/json/identity_client.py b/tempest/services/identity/v2/json/identity_client.py
index 8f76c74..1c1bfaa 100644
--- a/tempest/services/identity/v2/json/identity_client.py
+++ b/tempest/services/identity/v2/json/identity_client.py
@@ -213,7 +213,7 @@
self.expected_success(204, resp.status)
return service_client.ResponseBody(resp, body)
- def list_users_for_tenant(self, tenant_id):
+ def list_tenant_users(self, tenant_id):
"""List users for a Tenant."""
resp, body = self.get('/tenants/%s/users' % tenant_id)
self.expected_success(200, resp.status)
@@ -221,7 +221,7 @@
return service_client.ResponseBody(resp, body)
def get_user_by_username(self, tenant_id, username):
- users = self.list_users_for_tenant(tenant_id)['users']
+ users = self.list_tenant_users(tenant_id)['users']
for user in users:
if user['name'] == username:
return user