blob: 653a3cdf17463c85322ae296f5b457248ca7d382 [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
Yuiko Takadae9999d62014-03-06 09:22:54 +000022from tempest import test
Mate Lakat99ee9142012-09-14 12:34:46 +010023
Matthew Treinishb0a78fc2014-01-29 16:49:12 +000024CONF = config.CONF
25
Mate Lakat99ee9142012-09-14 12:34:46 +010026
ivan-zhuf2b00502013-10-18 10:06:52 +080027class LiveBlockMigrationTestJSON(base.BaseV2ComputeAdminTest):
Mate Lakat0ccf0eb2013-03-28 12:00:52 +000028 _host_key = 'OS-EXT-SRV-ATTR:host'
Mate Lakat99ee9142012-09-14 12:34:46 +010029
Mate Lakat99ee9142012-09-14 12:34:46 +010030 @classmethod
Timofey Durakovad7aea52015-10-12 13:37:44 +030031 def skip_checks(cls):
32 super(LiveBlockMigrationTestJSON, cls).skip_checks()
33
34 if not CONF.compute_feature_enabled.live_migration:
35 skip_msg = ("%s skipped as live-migration is "
36 "not available" % cls.__name__)
37 raise cls.skipException(skip_msg)
Jordan Pittierf60c1002015-11-16 11:24:09 +010038 if CONF.compute.min_compute_nodes < 2:
Timofey Durakov7a04e912015-11-17 17:37:53 +030039 raise cls.skipException(
Timofey Durakovad7aea52015-10-12 13:37:44 +030040 "Less than 2 compute nodes, skipping migration test.")
41
42 @classmethod
Rohan Kanade60b73092015-02-04 17:58:19 +053043 def setup_clients(cls):
44 super(LiveBlockMigrationTestJSON, cls).setup_clients()
Attila Fazekas8e99b992013-02-24 09:53:23 +010045 cls.admin_hosts_client = cls.os_adm.hosts_client
46 cls.admin_servers_client = cls.os_adm.servers_client
ghanshyambed82762015-07-21 16:03:11 +090047 cls.admin_migration_client = cls.os_adm.migrations_client
Mate Lakat99ee9142012-09-14 12:34:46 +010048
Timofey Durakovad7aea52015-10-12 13:37:44 +030049 @classmethod
50 def _get_compute_hostnames(cls):
51 body = cls.admin_hosts_client.list_hosts()['hosts']
Mate Lakat99ee9142012-09-14 12:34:46 +010052 return [
53 host_record['host_name']
54 for host_record in body
55 if host_record['service'] == 'compute'
56 ]
57
58 def _get_server_details(self, server_id):
ghanshyam0f825252015-08-25 16:02:50 +090059 body = self.admin_servers_client.show_server(server_id)['server']
Mate Lakat99ee9142012-09-14 12:34:46 +010060 return body
61
62 def _get_host_for_server(self, server_id):
Mate Lakat0ccf0eb2013-03-28 12:00:52 +000063 return self._get_server_details(server_id)[self._host_key]
Mate Lakat99ee9142012-09-14 12:34:46 +010064
Timofey Durakovf358a7e2015-10-05 13:06:51 +030065 def _migrate_server_to(self, server_id, dest_host, volume_backed):
66 block_migration = (CONF.compute_feature_enabled.
67 block_migration_for_live_migration and
68 not volume_backed)
David Kranzae99b9a2015-02-16 13:37:01 -050069 body = self.admin_servers_client.live_migrate_server(
Timofey Durakovf358a7e2015-10-05 13:06:51 +030070 server_id, host=dest_host, block_migration=block_migration,
Ken'ichi Ohmichi86f58932015-08-18 04:16:15 +000071 disk_over_commit=False)
Mate Lakat99ee9142012-09-14 12:34:46 +010072 return body
73
74 def _get_host_other_than(self, host):
75 for target_host in self._get_compute_hostnames():
76 if host != target_host:
77 return target_host
78
Mate Lakat99ee9142012-09-14 12:34:46 +010079 def _get_server_status(self, server_id):
80 return self._get_server_details(server_id)['status']
81
Bob Ballc078be92013-04-09 14:25:00 +010082 def _volume_clean_up(self, server_id, volume_id):
John Warren6177c9e2015-08-19 20:00:17 +000083 body = self.volumes_client.show_volume(volume_id)['volume']
Bob Ballc078be92013-04-09 14:25:00 +010084 if body['status'] == 'in-use':
85 self.servers_client.detach_volume(server_id, volume_id)
86 self.volumes_client.wait_for_volume_status(volume_id, 'available')
87 self.volumes_client.delete_volume(volume_id)
88
Joe Gordon8843f0f2015-03-17 15:07:34 -070089 def _test_live_migration(self, state='ACTIVE', volume_backed=False):
90 """Tests live migration between two hosts.
Matt Riedemannbb9f7042015-03-03 08:53:11 -080091
92 Requires CONF.compute_feature_enabled.live_migration to be True.
93
94 :param state: The vm_state the migrated server should be in before and
95 after the live migration. Supported values are 'ACTIVE'
96 and 'PAUSED'.
Joe Gordon8843f0f2015-03-17 15:07:34 -070097 :param volume_backed: If the instance is volume backed or not. If
98 volume_backed, *block* migration is not used.
Matt Riedemannbb9f7042015-03-03 08:53:11 -080099 """
Timofey Durakovf358a7e2015-10-05 13:06:51 +0300100 # Live migrate an instance to another host
Jordan Pittier599a3562016-01-08 17:38:14 +0100101 server_id = self.create_test_server(wait_until="ACTIVE",
102 volume_backed=volume_backed)['id']
Mate Lakat99ee9142012-09-14 12:34:46 +0100103 actual_host = self._get_host_for_server(server_id)
Mate Lakat99ee9142012-09-14 12:34:46 +0100104 target_host = self._get_host_other_than(actual_host)
Matt Riedemannbb9f7042015-03-03 08:53:11 -0800105
106 if state == 'PAUSED':
107 self.admin_servers_client.pause_server(server_id)
Ken'ichi Ohmichi0eb153c2015-07-13 02:18:25 +0000108 waiters.wait_for_server_status(self.admin_servers_client,
109 server_id, state)
Matt Riedemannbb9f7042015-03-03 08:53:11 -0800110
Timofey Durakovf358a7e2015-10-05 13:06:51 +0300111 self._migrate_server_to(server_id, target_host, volume_backed)
Ken'ichi Ohmichi0eb153c2015-07-13 02:18:25 +0000112 waiters.wait_for_server_status(self.servers_client, server_id, state)
ghanshyam8a599492015-08-24 15:55:59 +0900113 migration_list = (self.admin_migration_client.list_migrations()
114 ['migrations'])
ghanshyambed82762015-07-21 16:03:11 +0900115
116 msg = ("Live Migration failed. Migrations list for Instance "
117 "%s: [" % server_id)
118 for live_migration in migration_list:
119 if (live_migration['instance_uuid'] == server_id):
120 msg += "\n%s" % live_migration
121 msg += "]"
122 self.assertEqual(target_host, self._get_host_for_server(server_id),
123 msg)
Mate Lakat99ee9142012-09-14 12:34:46 +0100124
Matt Riedemannbb9f7042015-03-03 08:53:11 -0800125 @test.idempotent_id('1dce86b8-eb04-4c03-a9d8-9c1dc3ee0c7b')
Matt Riedemannbb9f7042015-03-03 08:53:11 -0800126 def test_live_block_migration(self):
Joe Gordon8843f0f2015-03-17 15:07:34 -0700127 self._test_live_migration()
Matt Riedemannbb9f7042015-03-03 08:53:11 -0800128
129 @test.idempotent_id('1e107f21-61b2-4988-8f22-b196e938ab88')
Matt Riedemannbb9f7042015-03-03 08:53:11 -0800130 @testtools.skipUnless(CONF.compute_feature_enabled.pause,
131 'Pause is not available.')
132 @testtools.skipUnless(CONF.compute_feature_enabled
133 .live_migrate_paused_instances,
134 'Live migration of paused instances is not '
135 'available.')
136 def test_live_block_migration_paused(self):
Joe Gordon8843f0f2015-03-17 15:07:34 -0700137 self._test_live_migration(state='PAUSED')
138
139 @test.idempotent_id('5071cf17-3004-4257-ae61-73a84e28badd')
Joe Gordon8843f0f2015-03-17 15:07:34 -0700140 @test.services('volume')
141 def test_volume_backed_live_migration(self):
142 self._test_live_migration(volume_backed=True)
Matt Riedemannbb9f7042015-03-03 08:53:11 -0800143
Chris Hoge7579c1a2015-02-26 14:12:15 -0800144 @test.idempotent_id('e19c0cc6-6720-4ed8-be83-b6603ed5c812')
Timofey Durakovad7aea52015-10-12 13:37:44 +0300145 @testtools.skipIf(not CONF.compute_feature_enabled.
Matthew Treinishd5c96022013-10-17 21:51:23 +0000146 block_migration_for_live_migration,
Bob Ballc078be92013-04-09 14:25:00 +0100147 'Block Live migration not available')
Matthew Treinishd5c96022013-10-17 21:51:23 +0000148 @testtools.skipIf(not CONF.compute_feature_enabled.
149 block_migrate_cinder_iscsi,
Bob Ballc078be92013-04-09 14:25:00 +0100150 'Block Live migration not configured for iSCSI')
151 def test_iscsi_volume(self):
Jordan Pittier599a3562016-01-08 17:38:14 +0100152 server_id = self.create_test_server(wait_until="ACTIVE")['id']
Bob Ballc078be92013-04-09 14:25:00 +0100153 actual_host = self._get_host_for_server(server_id)
154 target_host = self._get_host_other_than(actual_host)
155
John Warren6177c9e2015-08-19 20:00:17 +0000156 volume = self.volumes_client.create_volume(
157 display_name='test')['volume']
Bob Ballc078be92013-04-09 14:25:00 +0100158
159 self.volumes_client.wait_for_volume_status(volume['id'],
160 'available')
161 self.addCleanup(self._volume_clean_up, server_id, volume['id'])
162
163 # Attach the volume to the server
Ken'ichi Ohmichidfc88de2015-08-13 05:12:20 +0000164 self.servers_client.attach_volume(server_id, volumeId=volume['id'],
Bob Ballc078be92013-04-09 14:25:00 +0100165 device='/dev/xvdb')
166 self.volumes_client.wait_for_volume_status(volume['id'], 'in-use')
167
168 self._migrate_server_to(server_id, target_host)
Ken'ichi Ohmichi0eb153c2015-07-13 02:18:25 +0000169 waiters.wait_for_server_status(self.servers_client,
170 server_id, 'ACTIVE')
Chang Bo Guofc77e932013-09-16 17:38:26 -0700171 self.assertEqual(target_host, self._get_host_for_server(server_id))