blob: 410f7b7f3f18191a826ace7ed29f61b200354aa2 [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
Rohan Kanade60b73092015-02-04 17:58:19 +053031 def setup_clients(cls):
32 super(LiveBlockMigrationTestJSON, cls).setup_clients()
Attila Fazekas8e99b992013-02-24 09:53:23 +010033 cls.admin_hosts_client = cls.os_adm.hosts_client
34 cls.admin_servers_client = cls.os_adm.servers_client
ghanshyambed82762015-07-21 16:03:11 +090035 cls.admin_migration_client = cls.os_adm.migrations_client
Mate Lakat99ee9142012-09-14 12:34:46 +010036
Rohan Kanade60b73092015-02-04 17:58:19 +053037 @classmethod
38 def resource_setup(cls):
39 super(LiveBlockMigrationTestJSON, cls).resource_setup()
40
Mate Lakat99ee9142012-09-14 12:34:46 +010041 cls.created_server_ids = []
42
43 def _get_compute_hostnames(self):
ghanshyame1bd29e2015-08-18 16:47:24 +090044 body = self.admin_hosts_client.list_hosts()['hosts']
Mate Lakat99ee9142012-09-14 12:34:46 +010045 return [
46 host_record['host_name']
47 for host_record in body
48 if host_record['service'] == 'compute'
49 ]
50
51 def _get_server_details(self, server_id):
Ken'ichi Ohmichi76800242015-07-03 05:12:31 +000052 body = self.admin_servers_client.show_server(server_id)
Mate Lakat99ee9142012-09-14 12:34:46 +010053 return body
54
55 def _get_host_for_server(self, server_id):
Mate Lakat0ccf0eb2013-03-28 12:00:52 +000056 return self._get_server_details(server_id)[self._host_key]
Mate Lakat99ee9142012-09-14 12:34:46 +010057
58 def _migrate_server_to(self, server_id, dest_host):
Ken'ichi Ohmichi86f58932015-08-18 04:16:15 +000059 bmflm = CONF.compute_feature_enabled.block_migration_for_live_migration
David Kranzae99b9a2015-02-16 13:37:01 -050060 body = self.admin_servers_client.live_migrate_server(
Ken'ichi Ohmichi86f58932015-08-18 04:16:15 +000061 server_id, host=dest_host, block_migration=bmflm,
62 disk_over_commit=False)
Mate Lakat99ee9142012-09-14 12:34:46 +010063 return body
64
65 def _get_host_other_than(self, host):
66 for target_host in self._get_compute_hostnames():
67 if host != target_host:
68 return target_host
69
Mate Lakat99ee9142012-09-14 12:34:46 +010070 def _get_server_status(self, server_id):
71 return self._get_server_details(server_id)['status']
72
73 def _get_an_active_server(self):
74 for server_id in self.created_server_ids:
75 if 'ACTIVE' == self._get_server_status(server_id):
76 return server_id
77 else:
David Kranz0fb14292015-02-11 15:55:20 -050078 server = self.create_test_server(wait_until="ACTIVE")
Mate Lakat99ee9142012-09-14 12:34:46 +010079 server_id = server['id']
Mate Lakat99ee9142012-09-14 12:34:46 +010080 self.created_server_ids.append(server_id)
81 return server_id
82
Bob Ballc078be92013-04-09 14:25:00 +010083 def _volume_clean_up(self, server_id, volume_id):
John Warren6177c9e2015-08-19 20:00:17 +000084 body = self.volumes_client.show_volume(volume_id)['volume']
Bob Ballc078be92013-04-09 14:25:00 +010085 if body['status'] == 'in-use':
86 self.servers_client.detach_volume(server_id, volume_id)
87 self.volumes_client.wait_for_volume_status(volume_id, 'available')
88 self.volumes_client.delete_volume(volume_id)
89
Matt Riedemannbb9f7042015-03-03 08:53:11 -080090 def _test_live_block_migration(self, state='ACTIVE'):
91 """Tests live block migration between two hosts.
92
93 Requires CONF.compute_feature_enabled.live_migration to be True.
94
95 :param state: The vm_state the migrated server should be in before and
96 after the live migration. Supported values are 'ACTIVE'
97 and 'PAUSED'.
98 """
Sean Dague4dd2c0b2013-01-03 17:50:28 -050099 # Live block migrate an instance to another host
Mate Lakat99ee9142012-09-14 12:34:46 +0100100 if len(self._get_compute_hostnames()) < 2:
ivan-zhu1feeb382013-01-24 10:14:39 +0800101 raise self.skipTest(
Mate Lakat99ee9142012-09-14 12:34:46 +0100102 "Less than 2 compute nodes, skipping migration test.")
Mate Lakat99ee9142012-09-14 12:34:46 +0100103 server_id = self._get_an_active_server()
Mate Lakat99ee9142012-09-14 12:34:46 +0100104 actual_host = self._get_host_for_server(server_id)
Mate Lakat99ee9142012-09-14 12:34:46 +0100105 target_host = self._get_host_other_than(actual_host)
Matt Riedemannbb9f7042015-03-03 08:53:11 -0800106
107 if state == 'PAUSED':
108 self.admin_servers_client.pause_server(server_id)
Ken'ichi Ohmichi0eb153c2015-07-13 02:18:25 +0000109 waiters.wait_for_server_status(self.admin_servers_client,
110 server_id, state)
Matt Riedemannbb9f7042015-03-03 08:53:11 -0800111
Mate Lakat99ee9142012-09-14 12:34:46 +0100112 self._migrate_server_to(server_id, target_host)
Ken'ichi Ohmichi0eb153c2015-07-13 02:18:25 +0000113 waiters.wait_for_server_status(self.servers_client, server_id, state)
ghanshyam8a599492015-08-24 15:55:59 +0900114 migration_list = (self.admin_migration_client.list_migrations()
115 ['migrations'])
ghanshyambed82762015-07-21 16:03:11 +0900116
117 msg = ("Live Migration failed. Migrations list for Instance "
118 "%s: [" % server_id)
119 for live_migration in migration_list:
120 if (live_migration['instance_uuid'] == server_id):
121 msg += "\n%s" % live_migration
122 msg += "]"
123 self.assertEqual(target_host, self._get_host_for_server(server_id),
124 msg)
Mate Lakat99ee9142012-09-14 12:34:46 +0100125
Matt Riedemannbb9f7042015-03-03 08:53:11 -0800126 @test.idempotent_id('1dce86b8-eb04-4c03-a9d8-9c1dc3ee0c7b')
127 @testtools.skipUnless(CONF.compute_feature_enabled.live_migration,
128 'Live migration not available')
129 def test_live_block_migration(self):
130 self._test_live_block_migration()
131
132 @test.idempotent_id('1e107f21-61b2-4988-8f22-b196e938ab88')
133 @testtools.skipUnless(CONF.compute_feature_enabled.live_migration,
134 'Live migration not available')
135 @testtools.skipUnless(CONF.compute_feature_enabled.pause,
136 'Pause is not available.')
137 @testtools.skipUnless(CONF.compute_feature_enabled
138 .live_migrate_paused_instances,
139 'Live migration of paused instances is not '
140 'available.')
141 def test_live_block_migration_paused(self):
142 self._test_live_block_migration(state='PAUSED')
143
Chris Hoge7579c1a2015-02-26 14:12:15 -0800144 @test.idempotent_id('e19c0cc6-6720-4ed8-be83-b6603ed5c812')
Matthew Treinishd5c96022013-10-17 21:51:23 +0000145 @testtools.skipIf(not CONF.compute_feature_enabled.live_migration or not
146 CONF.compute_feature_enabled.
147 block_migration_for_live_migration,
Bob Ballc078be92013-04-09 14:25:00 +0100148 'Block Live migration not available')
Matthew Treinishd5c96022013-10-17 21:51:23 +0000149 @testtools.skipIf(not CONF.compute_feature_enabled.
150 block_migrate_cinder_iscsi,
Bob Ballc078be92013-04-09 14:25:00 +0100151 'Block Live migration not configured for iSCSI')
152 def test_iscsi_volume(self):
153 # Live block migrate an instance to another host
154 if len(self._get_compute_hostnames()) < 2:
155 raise self.skipTest(
156 "Less than 2 compute nodes, skipping migration test.")
157 server_id = self._get_an_active_server()
158 actual_host = self._get_host_for_server(server_id)
159 target_host = self._get_host_other_than(actual_host)
160
John Warren6177c9e2015-08-19 20:00:17 +0000161 volume = self.volumes_client.create_volume(
162 display_name='test')['volume']
Bob Ballc078be92013-04-09 14:25:00 +0100163
164 self.volumes_client.wait_for_volume_status(volume['id'],
165 'available')
166 self.addCleanup(self._volume_clean_up, server_id, volume['id'])
167
168 # Attach the volume to the server
Ken'ichi Ohmichidfc88de2015-08-13 05:12:20 +0000169 self.servers_client.attach_volume(server_id, volumeId=volume['id'],
Bob Ballc078be92013-04-09 14:25:00 +0100170 device='/dev/xvdb')
171 self.volumes_client.wait_for_volume_status(volume['id'], 'in-use')
172
173 self._migrate_server_to(server_id, target_host)
Ken'ichi Ohmichi0eb153c2015-07-13 02:18:25 +0000174 waiters.wait_for_server_status(self.servers_client,
175 server_id, 'ACTIVE')
Chang Bo Guofc77e932013-09-16 17:38:26 -0700176 self.assertEqual(target_host, self._get_host_for_server(server_id))