blob: fa8a7379c334b760134cb4578d9cc395be1d005e [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(
Martin Kopec213d0a42023-11-30 10:28:14 +010077 name=data_utils.rand_name(
78 prefix=CONF.resource_name_prefix,
79 name='test_resize_flavor_'),
Matt Riedemann98c32b72016-04-18 19:34:47 -040080 ram=flavor['ram'],
81 disk=flavor['disk'],
82 vcpus=flavor['vcpus']
83 )['flavor']
84 self.addCleanup(self._flavor_clean_up, flavor['id'])
85
zhuflc88e0a12017-12-28 11:30:01 +080086 # Set extra specs same as self.flavor_ref for the created flavor,
87 # because the environment may need some special extra specs to
88 # create server which should have been contained in
89 # self.flavor_ref.
90 extra_spec_keys = self.admin_flavors_client.list_flavor_extra_specs(
91 self.flavor_ref)['extra_specs']
92 if extra_spec_keys:
93 self.admin_flavors_client.set_flavor_extra_spec(
94 flavor['id'], **extra_spec_keys)
95
Matt Riedemann98c32b72016-04-18 19:34:47 -040096 # Now boot a server with the copied flavor.
97 server = self.create_test_server(
98 wait_until='ACTIVE', flavor=flavor['id'])
zhufl4e7b2f42020-08-20 09:09:06 +080099 server = self.servers_client.show_server(server['id'])['server']
100
101 # If 'id' not in server['flavor'], we can only compare the flavor
102 # details, so here we should save the to-be-deleted flavor's details,
103 # for the flavor comparison after the server resizing.
104 if not server['flavor'].get('id'):
105 pre_flavor = {}
106 body = self.flavors_client.show_flavor(flavor['id'])['flavor']
107 for key in ['name', 'ram', 'vcpus', 'disk']:
108 pre_flavor[key] = body[key]
Matt Riedemann98c32b72016-04-18 19:34:47 -0400109
110 # Delete the flavor we used to boot the instance.
111 self._flavor_clean_up(flavor['id'])
112
113 # Now resize the server and wait for it to go into verify state.
114 self.servers_client.resize_server(server['id'], self.flavor_ref_alt)
115 waiters.wait_for_server_status(self.servers_client, server['id'],
116 'VERIFY_RESIZE')
117
118 # Now revert the resize, it should be OK even though the original
119 # flavor used to boot the server was deleted.
120 self.servers_client.revert_resize_server(server['id'])
121 waiters.wait_for_server_status(self.servers_client, server['id'],
122 'ACTIVE')
123
124 server = self.servers_client.show_server(server['id'])['server']
zhufl4e7b2f42020-08-20 09:09:06 +0800125 if server['flavor'].get('id'):
126 msg = ('server flavor is not same as flavor!')
127 self.assertEqual(flavor['id'], server['flavor']['id'], msg)
128 else:
129 self.assertEqual(pre_flavor['name'],
130 server['flavor']['original_name'],
131 "original_name in server flavor is not same as "
132 "flavor name!")
133 for key in ['ram', 'vcpus', 'disk']:
134 msg = ('attribute %s in server flavor is not same as '
135 'flavor!' % key)
136 self.assertEqual(pre_flavor[key], server['flavor'][key], msg)
Ludovic Beliveauae314882016-09-15 13:34:14 -0400137
Ludovic Beliveau20c03bc2016-09-15 14:25:58 -0400138 def _test_cold_migrate_server(self, revert=False):
Ludovic Beliveauae314882016-09-15 13:34:14 -0400139 if CONF.compute.min_compute_nodes < 2:
140 msg = "Less than 2 compute nodes, skipping multinode tests."
141 raise self.skipException(msg)
142
143 server = self.create_test_server(wait_until="ACTIVE")
zhufl7bc916d2018-08-22 14:47:39 +0800144 src_host = self.get_host_for_server(server['id'])
Ludovic Beliveauae314882016-09-15 13:34:14 -0400145
146 self.admin_servers_client.migrate_server(server['id'])
147
148 waiters.wait_for_server_status(self.servers_client,
149 server['id'], 'VERIFY_RESIZE')
150
Ludovic Beliveau20c03bc2016-09-15 14:25:58 -0400151 if revert:
152 self.servers_client.revert_resize_server(server['id'])
153 assert_func = self.assertEqual
154 else:
155 self.servers_client.confirm_resize_server(server['id'])
156 assert_func = self.assertNotEqual
157
Ludovic Beliveauae314882016-09-15 13:34:14 -0400158 waiters.wait_for_server_status(self.servers_client,
159 server['id'], 'ACTIVE')
zhufl7bc916d2018-08-22 14:47:39 +0800160 dst_host = self.get_host_for_server(server['id'])
Ludovic Beliveau20c03bc2016-09-15 14:25:58 -0400161 assert_func(src_host, dst_host)
Ludovic Beliveauae314882016-09-15 13:34:14 -0400162
Ghanshyam Manne2183ca2023-02-10 19:31:52 -0600163 @decorators.attr(type='multinode')
Ken'ichi Ohmichiebbfd1c2017-01-27 16:37:00 -0800164 @decorators.idempotent_id('4bf0be52-3b6f-4746-9a27-3143636fe30d')
Ludovic Beliveau20c03bc2016-09-15 14:25:58 -0400165 @testtools.skipUnless(CONF.compute_feature_enabled.cold_migration,
166 'Cold migration not available.')
167 def test_cold_migration(self):
zhufl1b3b03d2020-04-16 08:38:16 +0800168 """Test cold migrating server and then confirm the migration"""
Ludovic Beliveau20c03bc2016-09-15 14:25:58 -0400169 self._test_cold_migrate_server(revert=False)
170
Ghanshyam Manne2183ca2023-02-10 19:31:52 -0600171 @decorators.attr(type='multinode')
Ken'ichi Ohmichiebbfd1c2017-01-27 16:37:00 -0800172 @decorators.idempotent_id('caa1aa8b-f4ef-4374-be0d-95f001c2ac2d')
Ludovic Beliveau20c03bc2016-09-15 14:25:58 -0400173 @testtools.skipUnless(CONF.compute_feature_enabled.cold_migration,
174 'Cold migration not available.')
175 def test_revert_cold_migration(self):
zhufl1b3b03d2020-04-16 08:38:16 +0800176 """Test cold migrating server and then revert the migration"""
Ludovic Beliveau20c03bc2016-09-15 14:25:58 -0400177 self._test_cold_migrate_server(revert=True)