blob: 18a6afcf3c3650414a87dbd71493a5736e81c4ae [file] [log] [blame]
ZhiQiang Fan39f97222013-09-20 04:49:44 +08001# Copyright 2012 OpenStack Foundation
Mate Lakat99ee9142012-09-14 12:34:46 +01002# All Rights Reserved.
3#
4# Licensed under the Apache License, Version 2.0 (the "License"); you may
5# not use this file except in compliance with the License. You may obtain
6# a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13# License for the specific language governing permissions and limitations
14# under the License.
15
Mate Lakat99ee9142012-09-14 12:34:46 +010016
ivan-zhu1feeb382013-01-24 10:14:39 +080017import testtools
Matthew Treinisha83a16e2012-12-07 13:44:02 -050018
Sean Dague1937d092013-05-17 16:36:38 -040019from tempest.api.compute import base
Ken'ichi Ohmichi0eb153c2015-07-13 02:18:25 +000020from tempest.common import waiters
Mate Lakat99ee9142012-09-14 12:34:46 +010021from tempest import config
Brian Haleya3879b52016-02-24 16:53:47 -060022from tempest.lib import decorators
Yuiko Takadae9999d62014-03-06 09:22:54 +000023from tempest import test
Mate Lakat99ee9142012-09-14 12:34:46 +010024
Matthew Treinishb0a78fc2014-01-29 16:49:12 +000025CONF = config.CONF
26
Mate Lakat99ee9142012-09-14 12:34:46 +010027
ivan-zhuf2b00502013-10-18 10:06:52 +080028class LiveBlockMigrationTestJSON(base.BaseV2ComputeAdminTest):
Eli Qiaoe07eacc2016-03-03 13:49:37 +080029 max_microversion = '2.24'
30 block_migration = None
Mate Lakat99ee9142012-09-14 12:34:46 +010031
Mate Lakat99ee9142012-09-14 12:34:46 +010032 @classmethod
Timofey Durakovad7aea52015-10-12 13:37:44 +030033 def skip_checks(cls):
34 super(LiveBlockMigrationTestJSON, cls).skip_checks()
35
36 if not CONF.compute_feature_enabled.live_migration:
37 skip_msg = ("%s skipped as live-migration is "
38 "not available" % cls.__name__)
39 raise cls.skipException(skip_msg)
Jordan Pittierf60c1002015-11-16 11:24:09 +010040 if CONF.compute.min_compute_nodes < 2:
Timofey Durakov7a04e912015-11-17 17:37:53 +030041 raise cls.skipException(
Timofey Durakovad7aea52015-10-12 13:37:44 +030042 "Less than 2 compute nodes, skipping migration test.")
43
44 @classmethod
Rohan Kanade60b73092015-02-04 17:58:19 +053045 def setup_clients(cls):
46 super(LiveBlockMigrationTestJSON, cls).setup_clients()
Attila Fazekas8e99b992013-02-24 09:53:23 +010047 cls.admin_hosts_client = cls.os_adm.hosts_client
48 cls.admin_servers_client = cls.os_adm.servers_client
ghanshyambed82762015-07-21 16:03:11 +090049 cls.admin_migration_client = cls.os_adm.migrations_client
Mate Lakat99ee9142012-09-14 12:34:46 +010050
Timofey Durakovad7aea52015-10-12 13:37:44 +030051 @classmethod
52 def _get_compute_hostnames(cls):
53 body = cls.admin_hosts_client.list_hosts()['hosts']
Mate Lakat99ee9142012-09-14 12:34:46 +010054 return [
55 host_record['host_name']
56 for host_record in body
57 if host_record['service'] == 'compute'
58 ]
59
60 def _get_server_details(self, server_id):
ghanshyam0f825252015-08-25 16:02:50 +090061 body = self.admin_servers_client.show_server(server_id)['server']
Mate Lakat99ee9142012-09-14 12:34:46 +010062 return body
63
64 def _get_host_for_server(self, server_id):
Ken'ichi Ohmichi70456892016-08-12 14:31:19 -070065 return self._get_server_details(server_id)['OS-EXT-SRV-ATTR:host']
Mate Lakat99ee9142012-09-14 12:34:46 +010066
Claudiu Belu516b7a42016-03-03 06:28:43 -080067 def _migrate_server_to(self, server_id, dest_host, volume_backed=False):
Eli Qiaoe07eacc2016-03-03 13:49:37 +080068 kwargs = dict()
69 block_migration = getattr(self, 'block_migration', None)
70 if self.block_migration is None:
71 kwargs['disk_over_commit'] = False
72 block_migration = (CONF.compute_feature_enabled.
73 block_migration_for_live_migration and
74 not volume_backed)
David Kranzae99b9a2015-02-16 13:37:01 -050075 body = self.admin_servers_client.live_migrate_server(
Timofey Durakovf358a7e2015-10-05 13:06:51 +030076 server_id, host=dest_host, block_migration=block_migration,
Eli Qiaoe07eacc2016-03-03 13:49:37 +080077 **kwargs)
Mate Lakat99ee9142012-09-14 12:34:46 +010078 return body
79
80 def _get_host_other_than(self, host):
81 for target_host in self._get_compute_hostnames():
82 if host != target_host:
83 return target_host
84
Bob Ballc078be92013-04-09 14:25:00 +010085 def _volume_clean_up(self, server_id, volume_id):
John Warren6177c9e2015-08-19 20:00:17 +000086 body = self.volumes_client.show_volume(volume_id)['volume']
Bob Ballc078be92013-04-09 14:25:00 +010087 if body['status'] == 'in-use':
88 self.servers_client.detach_volume(server_id, volume_id)
Yaroslav Lobankoved3a35b2016-03-24 22:41:30 -050089 waiters.wait_for_volume_status(self.volumes_client,
90 volume_id, 'available')
Bob Ballc078be92013-04-09 14:25:00 +010091 self.volumes_client.delete_volume(volume_id)
92
Joe Gordon8843f0f2015-03-17 15:07:34 -070093 def _test_live_migration(self, state='ACTIVE', volume_backed=False):
94 """Tests live migration between two hosts.
Matt Riedemannbb9f7042015-03-03 08:53:11 -080095
96 Requires CONF.compute_feature_enabled.live_migration to be True.
97
98 :param state: The vm_state the migrated server should be in before and
99 after the live migration. Supported values are 'ACTIVE'
100 and 'PAUSED'.
Joe Gordon8843f0f2015-03-17 15:07:34 -0700101 :param volume_backed: If the instance is volume backed or not. If
102 volume_backed, *block* migration is not used.
Matt Riedemannbb9f7042015-03-03 08:53:11 -0800103 """
Timofey Durakovf358a7e2015-10-05 13:06:51 +0300104 # Live migrate an instance to another host
Jordan Pittier599a3562016-01-08 17:38:14 +0100105 server_id = self.create_test_server(wait_until="ACTIVE",
106 volume_backed=volume_backed)['id']
Mate Lakat99ee9142012-09-14 12:34:46 +0100107 actual_host = self._get_host_for_server(server_id)
Mate Lakat99ee9142012-09-14 12:34:46 +0100108 target_host = self._get_host_other_than(actual_host)
Matt Riedemannbb9f7042015-03-03 08:53:11 -0800109
110 if state == 'PAUSED':
111 self.admin_servers_client.pause_server(server_id)
Ken'ichi Ohmichi0eb153c2015-07-13 02:18:25 +0000112 waiters.wait_for_server_status(self.admin_servers_client,
113 server_id, state)
Matt Riedemannbb9f7042015-03-03 08:53:11 -0800114
Timofey Durakovf358a7e2015-10-05 13:06:51 +0300115 self._migrate_server_to(server_id, target_host, volume_backed)
Ken'ichi Ohmichi0eb153c2015-07-13 02:18:25 +0000116 waiters.wait_for_server_status(self.servers_client, server_id, state)
ghanshyam8a599492015-08-24 15:55:59 +0900117 migration_list = (self.admin_migration_client.list_migrations()
118 ['migrations'])
ghanshyambed82762015-07-21 16:03:11 +0900119
120 msg = ("Live Migration failed. Migrations list for Instance "
121 "%s: [" % server_id)
122 for live_migration in migration_list:
123 if (live_migration['instance_uuid'] == server_id):
124 msg += "\n%s" % live_migration
125 msg += "]"
126 self.assertEqual(target_host, self._get_host_for_server(server_id),
127 msg)
Mate Lakat99ee9142012-09-14 12:34:46 +0100128
Matt Riedemannbb9f7042015-03-03 08:53:11 -0800129 @test.idempotent_id('1dce86b8-eb04-4c03-a9d8-9c1dc3ee0c7b')
Matt Riedemannbb9f7042015-03-03 08:53:11 -0800130 def test_live_block_migration(self):
Joe Gordon8843f0f2015-03-17 15:07:34 -0700131 self._test_live_migration()
Matt Riedemannbb9f7042015-03-03 08:53:11 -0800132
133 @test.idempotent_id('1e107f21-61b2-4988-8f22-b196e938ab88')
Matt Riedemannbb9f7042015-03-03 08:53:11 -0800134 @testtools.skipUnless(CONF.compute_feature_enabled.pause,
135 'Pause is not available.')
Matt Riedemannbb9f7042015-03-03 08:53:11 -0800136 def test_live_block_migration_paused(self):
Joe Gordon8843f0f2015-03-17 15:07:34 -0700137 self._test_live_migration(state='PAUSED')
138
Brian Haleya3879b52016-02-24 16:53:47 -0600139 @decorators.skip_because(bug="1549511",
140 condition=CONF.service_available.neutron)
Joe Gordon8843f0f2015-03-17 15:07:34 -0700141 @test.idempotent_id('5071cf17-3004-4257-ae61-73a84e28badd')
Joe Gordon8843f0f2015-03-17 15:07:34 -0700142 @test.services('volume')
143 def test_volume_backed_live_migration(self):
144 self._test_live_migration(volume_backed=True)
Matt Riedemannbb9f7042015-03-03 08:53:11 -0800145
Chris Hoge7579c1a2015-02-26 14:12:15 -0800146 @test.idempotent_id('e19c0cc6-6720-4ed8-be83-b6603ed5c812')
Timofey Durakovad7aea52015-10-12 13:37:44 +0300147 @testtools.skipIf(not CONF.compute_feature_enabled.
Matthew Treinishd5c96022013-10-17 21:51:23 +0000148 block_migration_for_live_migration,
Bob Ballc078be92013-04-09 14:25:00 +0100149 'Block Live migration not available')
Matthew Treinishd5c96022013-10-17 21:51:23 +0000150 @testtools.skipIf(not CONF.compute_feature_enabled.
151 block_migrate_cinder_iscsi,
Bob Ballc078be92013-04-09 14:25:00 +0100152 'Block Live migration not configured for iSCSI')
153 def test_iscsi_volume(self):
Jordan Pittier599a3562016-01-08 17:38:14 +0100154 server_id = self.create_test_server(wait_until="ACTIVE")['id']
Bob Ballc078be92013-04-09 14:25:00 +0100155 actual_host = self._get_host_for_server(server_id)
156 target_host = self._get_host_other_than(actual_host)
157
John Warren6177c9e2015-08-19 20:00:17 +0000158 volume = self.volumes_client.create_volume(
Ken'ichi Ohmichiadb905e2016-08-26 15:16:23 -0700159 size=CONF.volume.volume_size, display_name='test')['volume']
Bob Ballc078be92013-04-09 14:25:00 +0100160
Yaroslav Lobankoved3a35b2016-03-24 22:41:30 -0500161 waiters.wait_for_volume_status(self.volumes_client,
162 volume['id'], 'available')
Bob Ballc078be92013-04-09 14:25:00 +0100163 self.addCleanup(self._volume_clean_up, server_id, volume['id'])
164
165 # Attach the volume to the server
Ken'ichi Ohmichidfc88de2015-08-13 05:12:20 +0000166 self.servers_client.attach_volume(server_id, volumeId=volume['id'],
Bob Ballc078be92013-04-09 14:25:00 +0100167 device='/dev/xvdb')
Yaroslav Lobankoved3a35b2016-03-24 22:41:30 -0500168 waiters.wait_for_volume_status(self.volumes_client,
169 volume['id'], 'in-use')
Bob Ballc078be92013-04-09 14:25:00 +0100170
171 self._migrate_server_to(server_id, target_host)
Ken'ichi Ohmichi0eb153c2015-07-13 02:18:25 +0000172 waiters.wait_for_server_status(self.servers_client,
173 server_id, 'ACTIVE')
Chang Bo Guofc77e932013-09-16 17:38:26 -0700174 self.assertEqual(target_host, self._get_host_for_server(server_id))
Eli Qiaoe07eacc2016-03-03 13:49:37 +0800175
176
177class LiveAutoBlockMigrationV225TestJSON(LiveBlockMigrationTestJSON):
178 min_microversion = '2.25'
179 max_microversion = 'latest'
180 block_migration = 'auto'