blob: 89152d6bab10193d6863516f549a86e096a8cfb5 [file] [log] [blame]
Ken'ichi Ohmichi2fdc1822014-03-18 09:10:57 +09001# Copyright 2014 NEC Corporation. All rights reserved.
2#
3# Licensed under the Apache License, Version 2.0 (the "License"); you may
4# not use this file except in compliance with the License. You may obtain
5# a copy of the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12# License for the specific language governing permissions and limitations
13# under the License.
14
15import testtools
16
17from tempest.api.compute import base
Ken'ichi Ohmichi0eb153c2015-07-13 02:18:25 +000018from tempest.common import waiters
Ken'ichi Ohmichi2fdc1822014-03-18 09:10:57 +090019from tempest import config
Ken'ichi Ohmichi757833a2017-03-10 10:30:30 -080020from tempest.lib.common.utils import data_utils
Ken'ichi Ohmichiebbfd1c2017-01-27 16:37:00 -080021from tempest.lib import decorators
Matt Riedemann98c32b72016-04-18 19:34:47 -040022from tempest.lib import exceptions
Ken'ichi Ohmichi2fdc1822014-03-18 09:10:57 +090023
24CONF = config.CONF
25
26
27class MigrationsAdminTest(base.BaseV2ComputeAdminTest):
zhufl1b3b03d2020-04-16 08:38:16 +080028 """Test migration operations supported by admin user"""
Ken'ichi Ohmichi2fdc1822014-03-18 09:10:57 +090029
30 @classmethod
Rohan Kanade60b73092015-02-04 17:58:19 +053031 def setup_clients(cls):
32 super(MigrationsAdminTest, cls).setup_clients()
Jordan Pittier8160d312017-04-18 11:52:23 +020033 cls.client = cls.os_admin.migrations_client
Ken'ichi Ohmichi2fdc1822014-03-18 09:10:57 +090034
Ken'ichi Ohmichiebbfd1c2017-01-27 16:37:00 -080035 @decorators.idempotent_id('75c0b83d-72a0-4cf8-a153-631e83e7d53f')
Ken'ichi Ohmichi2fdc1822014-03-18 09:10:57 +090036 def test_list_migrations(self):
zhufl1b3b03d2020-04-16 08:38:16 +080037 """Test admin user can get the migrations list"""
David Kranz5cf4ba42015-02-10 14:00:50 -050038 self.client.list_migrations()
Ken'ichi Ohmichi2fdc1822014-03-18 09:10:57 +090039
Ken'ichi Ohmichiebbfd1c2017-01-27 16:37:00 -080040 @decorators.idempotent_id('1b512062-8093-438e-b47a-37d2f597cd64')
Ken'ichi Ohmichi2fdc1822014-03-18 09:10:57 +090041 @testtools.skipUnless(CONF.compute_feature_enabled.resize,
42 'Resize not available.')
Ken'ichi Ohmichi2fdc1822014-03-18 09:10:57 +090043 def test_list_migrations_in_flavor_resize_situation(self):
zhufl1b3b03d2020-04-16 08:38:16 +080044 """Admin can get the migrations list containing the resized server"""
David Kranz0fb14292015-02-11 15:55:20 -050045 server = self.create_test_server(wait_until="ACTIVE")
Ken'ichi Ohmichi2fdc1822014-03-18 09:10:57 +090046 server_id = server['id']
47
zhufl3d018b02016-11-25 16:43:04 +080048 self.resize_server(server_id, self.flavor_ref_alt)
Ken'ichi Ohmichi2fdc1822014-03-18 09:10:57 +090049
ghanshyam8a599492015-08-24 15:55:59 +090050 body = self.client.list_migrations()['migrations']
Ken'ichi Ohmichi2fdc1822014-03-18 09:10:57 +090051
52 instance_uuids = [x['instance_uuid'] for x in body]
53 self.assertIn(server_id, instance_uuids)
Matt Riedemann98c32b72016-04-18 19:34:47 -040054
55 def _flavor_clean_up(self, flavor_id):
56 try:
zhuflfec7c592017-03-01 17:38:13 +080057 self.admin_flavors_client.delete_flavor(flavor_id)
58 self.admin_flavors_client.wait_for_resource_deletion(flavor_id)
Matt Riedemann98c32b72016-04-18 19:34:47 -040059 except exceptions.NotFound:
60 pass
61
Ken'ichi Ohmichiebbfd1c2017-01-27 16:37:00 -080062 @decorators.idempotent_id('33f1fec3-ba18-4470-8e4e-1d888e7c3593')
Matt Riedemann98c32b72016-04-18 19:34:47 -040063 @testtools.skipUnless(CONF.compute_feature_enabled.resize,
64 'Resize not available.')
65 def test_resize_server_revert_deleted_flavor(self):
zhufl1b3b03d2020-04-16 08:38:16 +080066 """Test reverting resized server with original flavor deleted
67
68 Tests that we can revert the resize on an instance whose original
69 flavor has been deleted.
70 """
Matt Riedemann98c32b72016-04-18 19:34:47 -040071
72 # First we have to create a flavor that we can delete so make a copy
73 # of the normal flavor from which we'd create a server.
zhuflfec7c592017-03-01 17:38:13 +080074 flavor = self.admin_flavors_client.show_flavor(
Matt Riedemann98c32b72016-04-18 19:34:47 -040075 self.flavor_ref)['flavor']
zhuflfec7c592017-03-01 17:38:13 +080076 flavor = self.admin_flavors_client.create_flavor(
Matt Riedemann98c32b72016-04-18 19:34:47 -040077 name=data_utils.rand_name('test_resize_flavor_'),
78 ram=flavor['ram'],
79 disk=flavor['disk'],
80 vcpus=flavor['vcpus']
81 )['flavor']
82 self.addCleanup(self._flavor_clean_up, flavor['id'])
83
zhuflc88e0a12017-12-28 11:30:01 +080084 # Set extra specs same as self.flavor_ref for the created flavor,
85 # because the environment may need some special extra specs to
86 # create server which should have been contained in
87 # self.flavor_ref.
88 extra_spec_keys = self.admin_flavors_client.list_flavor_extra_specs(
89 self.flavor_ref)['extra_specs']
90 if extra_spec_keys:
91 self.admin_flavors_client.set_flavor_extra_spec(
92 flavor['id'], **extra_spec_keys)
93
Matt Riedemann98c32b72016-04-18 19:34:47 -040094 # Now boot a server with the copied flavor.
95 server = self.create_test_server(
96 wait_until='ACTIVE', flavor=flavor['id'])
zhufl4e7b2f42020-08-20 09:09:06 +080097 server = self.servers_client.show_server(server['id'])['server']
98
99 # If 'id' not in server['flavor'], we can only compare the flavor
100 # details, so here we should save the to-be-deleted flavor's details,
101 # for the flavor comparison after the server resizing.
102 if not server['flavor'].get('id'):
103 pre_flavor = {}
104 body = self.flavors_client.show_flavor(flavor['id'])['flavor']
105 for key in ['name', 'ram', 'vcpus', 'disk']:
106 pre_flavor[key] = body[key]
Matt Riedemann98c32b72016-04-18 19:34:47 -0400107
108 # Delete the flavor we used to boot the instance.
109 self._flavor_clean_up(flavor['id'])
110
111 # Now resize the server and wait for it to go into verify state.
112 self.servers_client.resize_server(server['id'], self.flavor_ref_alt)
113 waiters.wait_for_server_status(self.servers_client, server['id'],
114 'VERIFY_RESIZE')
115
116 # Now revert the resize, it should be OK even though the original
117 # flavor used to boot the server was deleted.
118 self.servers_client.revert_resize_server(server['id'])
119 waiters.wait_for_server_status(self.servers_client, server['id'],
120 'ACTIVE')
121
122 server = self.servers_client.show_server(server['id'])['server']
zhufl4e7b2f42020-08-20 09:09:06 +0800123 if server['flavor'].get('id'):
124 msg = ('server flavor is not same as flavor!')
125 self.assertEqual(flavor['id'], server['flavor']['id'], msg)
126 else:
127 self.assertEqual(pre_flavor['name'],
128 server['flavor']['original_name'],
129 "original_name in server flavor is not same as "
130 "flavor name!")
131 for key in ['ram', 'vcpus', 'disk']:
132 msg = ('attribute %s in server flavor is not same as '
133 'flavor!' % key)
134 self.assertEqual(pre_flavor[key], server['flavor'][key], msg)
Ludovic Beliveauae314882016-09-15 13:34:14 -0400135
Ludovic Beliveau20c03bc2016-09-15 14:25:58 -0400136 def _test_cold_migrate_server(self, revert=False):
Ludovic Beliveauae314882016-09-15 13:34:14 -0400137 if CONF.compute.min_compute_nodes < 2:
138 msg = "Less than 2 compute nodes, skipping multinode tests."
139 raise self.skipException(msg)
140
141 server = self.create_test_server(wait_until="ACTIVE")
zhufl7bc916d2018-08-22 14:47:39 +0800142 src_host = self.get_host_for_server(server['id'])
Ludovic Beliveauae314882016-09-15 13:34:14 -0400143
144 self.admin_servers_client.migrate_server(server['id'])
145
146 waiters.wait_for_server_status(self.servers_client,
147 server['id'], 'VERIFY_RESIZE')
148
Ludovic Beliveau20c03bc2016-09-15 14:25:58 -0400149 if revert:
150 self.servers_client.revert_resize_server(server['id'])
151 assert_func = self.assertEqual
152 else:
153 self.servers_client.confirm_resize_server(server['id'])
154 assert_func = self.assertNotEqual
155
Ludovic Beliveauae314882016-09-15 13:34:14 -0400156 waiters.wait_for_server_status(self.servers_client,
157 server['id'], 'ACTIVE')
zhufl7bc916d2018-08-22 14:47:39 +0800158 dst_host = self.get_host_for_server(server['id'])
Ludovic Beliveau20c03bc2016-09-15 14:25:58 -0400159 assert_func(src_host, dst_host)
Ludovic Beliveauae314882016-09-15 13:34:14 -0400160
Ken'ichi Ohmichiebbfd1c2017-01-27 16:37:00 -0800161 @decorators.idempotent_id('4bf0be52-3b6f-4746-9a27-3143636fe30d')
Ludovic Beliveau20c03bc2016-09-15 14:25:58 -0400162 @testtools.skipUnless(CONF.compute_feature_enabled.cold_migration,
163 'Cold migration not available.')
164 def test_cold_migration(self):
zhufl1b3b03d2020-04-16 08:38:16 +0800165 """Test cold migrating server and then confirm the migration"""
Ludovic Beliveau20c03bc2016-09-15 14:25:58 -0400166 self._test_cold_migrate_server(revert=False)
167
Ken'ichi Ohmichiebbfd1c2017-01-27 16:37:00 -0800168 @decorators.idempotent_id('caa1aa8b-f4ef-4374-be0d-95f001c2ac2d')
Ludovic Beliveau20c03bc2016-09-15 14:25:58 -0400169 @testtools.skipUnless(CONF.compute_feature_enabled.cold_migration,
170 'Cold migration not available.')
171 def test_revert_cold_migration(self):
zhufl1b3b03d2020-04-16 08:38:16 +0800172 """Test cold migrating server and then revert the migration"""
Ludovic Beliveau20c03bc2016-09-15 14:25:58 -0400173 self._test_cold_migrate_server(revert=True)