blob: a7b6cd22c28c54b48a6f84a4867b75cfd4336aff [file] [log] [blame]
Mate Lakat99ee9142012-09-14 12:34:46 +01001# vim: tabstop=4 shiftwidth=4 softtabstop=4
2
ZhiQiang Fan39f97222013-09-20 04:49:44 +08003# Copyright 2012 OpenStack Foundation
Mate Lakat99ee9142012-09-14 12:34:46 +01004# All Rights Reserved.
5#
6# Licensed under the Apache License, Version 2.0 (the "License"); you may
7# not use this file except in compliance with the License. You may obtain
8# a copy of the License at
9#
10# http://www.apache.org/licenses/LICENSE-2.0
11#
12# Unless required by applicable law or agreed to in writing, software
13# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
14# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
15# License for the specific language governing permissions and limitations
16# under the License.
17
Mate Lakat99ee9142012-09-14 12:34:46 +010018import random
19import string
20
ivan-zhu1feeb382013-01-24 10:14:39 +080021import testtools
Matthew Treinisha83a16e2012-12-07 13:44:02 -050022
Sean Dague1937d092013-05-17 16:36:38 -040023from tempest.api.compute import base
Mate Lakat99ee9142012-09-14 12:34:46 +010024from tempest import config
25from tempest import exceptions
Chris Yeoh9465b0b2013-02-09 22:19:15 +103026from tempest.test import attr
Mate Lakat99ee9142012-09-14 12:34:46 +010027
28
ivan-zhuf2b00502013-10-18 10:06:52 +080029class LiveBlockMigrationTestJSON(base.BaseV2ComputeAdminTest):
Mate Lakat0ccf0eb2013-03-28 12:00:52 +000030 _host_key = 'OS-EXT-SRV-ATTR:host'
Attila Fazekas19044d52013-02-16 07:35:06 +010031 _interface = 'json'
Mate Lakat99ee9142012-09-14 12:34:46 +010032
Bob Ball0dca8972013-04-09 16:23:31 +010033 CONF = config.TempestConfig()
Mate Lakat99ee9142012-09-14 12:34:46 +010034
35 @classmethod
36 def setUpClass(cls):
ravikumar-venkatesan753262b2013-03-21 12:43:57 +000037 super(LiveBlockMigrationTestJSON, cls).setUpClass()
Mate Lakat99ee9142012-09-14 12:34:46 +010038
Attila Fazekas8e99b992013-02-24 09:53:23 +010039 cls.admin_hosts_client = cls.os_adm.hosts_client
40 cls.admin_servers_client = cls.os_adm.servers_client
Mate Lakat99ee9142012-09-14 12:34:46 +010041
42 cls.created_server_ids = []
43
44 def _get_compute_hostnames(self):
45 _resp, body = self.admin_hosts_client.list_hosts()
46 return [
47 host_record['host_name']
48 for host_record in body
49 if host_record['service'] == 'compute'
50 ]
51
52 def _get_server_details(self, server_id):
53 _resp, body = self.admin_servers_client.get_server(server_id)
54 return body
55
56 def _get_host_for_server(self, server_id):
Mate Lakat0ccf0eb2013-03-28 12:00:52 +000057 return self._get_server_details(server_id)[self._host_key]
Mate Lakat99ee9142012-09-14 12:34:46 +010058
59 def _migrate_server_to(self, server_id, dest_host):
60 _resp, body = self.admin_servers_client.live_migrate_server(
Bob Ball0dca8972013-04-09 16:23:31 +010061 server_id, dest_host,
Matthew Treinishd5c96022013-10-17 21:51:23 +000062 self.config.compute_feature_enabled.
63 block_migration_for_live_migration)
Mate Lakat99ee9142012-09-14 12:34:46 +010064 return body
65
66 def _get_host_other_than(self, host):
67 for target_host in self._get_compute_hostnames():
68 if host != target_host:
69 return target_host
70
71 def _get_non_existing_host_name(self):
72 random_name = ''.join(
73 random.choice(string.ascii_uppercase) for x in range(20))
74
Jaroslav Henner3c3d1792012-11-16 10:28:47 +010075 self.assertNotIn(random_name, self._get_compute_hostnames())
Mate Lakat99ee9142012-09-14 12:34:46 +010076
77 return random_name
78
79 def _get_server_status(self, server_id):
80 return self._get_server_details(server_id)['status']
81
82 def _get_an_active_server(self):
83 for server_id in self.created_server_ids:
84 if 'ACTIVE' == self._get_server_status(server_id):
85 return server_id
86 else:
Ken'ichi Ohmichicfc052e2013-10-23 11:50:04 +090087 _, server = self.create_test_server(wait_until="ACTIVE")
Mate Lakat99ee9142012-09-14 12:34:46 +010088 server_id = server['id']
89 self.password = server['adminPass']
90 self.password = 'password'
91 self.created_server_ids.append(server_id)
92 return server_id
93
Bob Ballc078be92013-04-09 14:25:00 +010094 def _volume_clean_up(self, server_id, volume_id):
95 resp, body = self.volumes_client.get_volume(volume_id)
96 if body['status'] == 'in-use':
97 self.servers_client.detach_volume(server_id, volume_id)
98 self.volumes_client.wait_for_volume_status(volume_id, 'available')
99 self.volumes_client.delete_volume(volume_id)
100
Matthew Treinishd5c96022013-10-17 21:51:23 +0000101 @testtools.skipIf(not CONF.compute_feature_enabled.live_migration,
Bob Ball0dca8972013-04-09 16:23:31 +0100102 'Live migration not available')
Giampaolo Lauriae9c77022013-05-22 01:23:58 -0400103 @attr(type='gate')
Attila Fazekas8e99b992013-02-24 09:53:23 +0100104 def test_live_block_migration(self):
Sean Dague4dd2c0b2013-01-03 17:50:28 -0500105 # Live block migrate an instance to another host
Mate Lakat99ee9142012-09-14 12:34:46 +0100106 if len(self._get_compute_hostnames()) < 2:
ivan-zhu1feeb382013-01-24 10:14:39 +0800107 raise self.skipTest(
Mate Lakat99ee9142012-09-14 12:34:46 +0100108 "Less than 2 compute nodes, skipping migration test.")
Mate Lakat99ee9142012-09-14 12:34:46 +0100109 server_id = self._get_an_active_server()
Mate Lakat99ee9142012-09-14 12:34:46 +0100110 actual_host = self._get_host_for_server(server_id)
Mate Lakat99ee9142012-09-14 12:34:46 +0100111 target_host = self._get_host_other_than(actual_host)
Mate Lakat99ee9142012-09-14 12:34:46 +0100112 self._migrate_server_to(server_id, target_host)
Mate Lakat99ee9142012-09-14 12:34:46 +0100113 self.servers_client.wait_for_server_status(server_id, 'ACTIVE')
Chang Bo Guofc77e932013-09-16 17:38:26 -0700114 self.assertEqual(target_host, self._get_host_for_server(server_id))
Mate Lakat99ee9142012-09-14 12:34:46 +0100115
Matthew Treinishd5c96022013-10-17 21:51:23 +0000116 @testtools.skipIf(not CONF.compute_feature_enabled.live_migration,
Bob Ball0dca8972013-04-09 16:23:31 +0100117 'Live migration not available')
Giampaolo Lauriae9c77022013-05-22 01:23:58 -0400118 @attr(type='gate')
Attila Fazekas8e99b992013-02-24 09:53:23 +0100119 def test_invalid_host_for_migration(self):
Sean Dague4dd2c0b2013-01-03 17:50:28 -0500120 # Migrating to an invalid host should not change the status
Mate Lakat99ee9142012-09-14 12:34:46 +0100121 server_id = self._get_an_active_server()
Mate Lakat99ee9142012-09-14 12:34:46 +0100122 target_host = self._get_non_existing_host_name()
123
Attila Fazekasfa756cb2013-02-12 10:52:42 +0100124 self.assertRaises(exceptions.BadRequest, self._migrate_server_to,
125 server_id, target_host)
Chang Bo Guofc77e932013-09-16 17:38:26 -0700126 self.assertEqual('ACTIVE', self._get_server_status(server_id))
Mate Lakat99ee9142012-09-14 12:34:46 +0100127
Matthew Treinishd5c96022013-10-17 21:51:23 +0000128 @testtools.skipIf(not CONF.compute_feature_enabled.live_migration or not
129 CONF.compute_feature_enabled.
130 block_migration_for_live_migration,
Bob Ballc078be92013-04-09 14:25:00 +0100131 'Block Live migration not available')
Matthew Treinishd5c96022013-10-17 21:51:23 +0000132 @testtools.skipIf(not CONF.compute_feature_enabled.
133 block_migrate_cinder_iscsi,
Bob Ballc078be92013-04-09 14:25:00 +0100134 'Block Live migration not configured for iSCSI')
Giampaolo Lauriae9c77022013-05-22 01:23:58 -0400135 @attr(type='gate')
Bob Ballc078be92013-04-09 14:25:00 +0100136 def test_iscsi_volume(self):
137 # Live block migrate an instance to another host
138 if len(self._get_compute_hostnames()) < 2:
139 raise self.skipTest(
140 "Less than 2 compute nodes, skipping migration test.")
141 server_id = self._get_an_active_server()
142 actual_host = self._get_host_for_server(server_id)
143 target_host = self._get_host_other_than(actual_host)
144
145 resp, volume = self.volumes_client.create_volume(1,
146 display_name='test')
147
148 self.volumes_client.wait_for_volume_status(volume['id'],
149 'available')
150 self.addCleanup(self._volume_clean_up, server_id, volume['id'])
151
152 # Attach the volume to the server
153 self.servers_client.attach_volume(server_id, volume['id'],
154 device='/dev/xvdb')
155 self.volumes_client.wait_for_volume_status(volume['id'], 'in-use')
156
157 self._migrate_server_to(server_id, target_host)
158 self.servers_client.wait_for_server_status(server_id, 'ACTIVE')
Chang Bo Guofc77e932013-09-16 17:38:26 -0700159 self.assertEqual(target_host, self._get_host_for_server(server_id))
Bob Ballc078be92013-04-09 14:25:00 +0100160
Mate Lakat99ee9142012-09-14 12:34:46 +0100161 @classmethod
162 def tearDownClass(cls):
163 for server_id in cls.created_server_ids:
164 cls.servers_client.delete_server(server_id)
165
ravikumar-venkatesan753262b2013-03-21 12:43:57 +0000166 super(LiveBlockMigrationTestJSON, cls).tearDownClass()
167
168
169class LiveBlockMigrationTestXML(LiveBlockMigrationTestJSON):
Mate Lakat0ccf0eb2013-03-28 12:00:52 +0000170 _host_key = (
171 '{http://docs.openstack.org/compute/ext/extended_status/api/v1.1}host')
ravikumar-venkatesan753262b2013-03-21 12:43:57 +0000172 _interface = 'xml'