blob: 03008f3ef9e030868d753cf6dbb02c570ad233bc [file] [log] [blame]
ZhiQiang Fan39f97222013-09-20 04:49:44 +08001# Copyright 2012 OpenStack Foundation
Jay Pipes13b479b2012-06-11 14:52:27 -04002# 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
Daryl Walleck6b9b2882012-04-08 21:43:39 -050016import base64
Jay Pipes13b479b2012-06-11 14:52:27 -040017
Mauro S. M. Rodrigues54110362013-02-15 13:14:04 -050018import netaddr
ivan-zhu1feeb382013-01-24 10:14:39 +080019import testtools
Jay Pipes13b479b2012-06-11 14:52:27 -040020
Sean Dague1937d092013-05-17 16:36:38 -040021from tempest.api.compute import base
Masayuki Igawa259c1132013-10-31 17:48:44 +090022from tempest.common.utils import data_utils
Masayuki Igawa209fd502014-02-17 14:46:43 +090023from tempest.common.utils.linux import remote_client
Sean Dague86bd8422013-12-20 09:56:44 -050024from tempest import config
Masayuki Igawa209fd502014-02-17 14:46:43 +090025from tempest import test
Daryl Walleck6b9b2882012-04-08 21:43:39 -050026
Sean Dague86bd8422013-12-20 09:56:44 -050027CONF = config.CONF
28
Daryl Walleck6b9b2882012-04-08 21:43:39 -050029
ivan-zhuf2b00502013-10-18 10:06:52 +080030class ServersTestJSON(base.BaseV2ComputeTest):
ivan-zhua5141d92013-03-06 23:12:43 +080031 disk_config = 'AUTO'
Daryl Walleck6b9b2882012-04-08 21:43:39 -050032
Attila Fazekas19044d52013-02-16 07:35:06 +010033 @classmethod
Rohan Kanade60b73092015-02-04 17:58:19 +053034 def setup_credentials(cls):
Attila Fazekas423834d2014-03-14 17:33:13 +010035 cls.prepare_instance_network()
Rohan Kanade60b73092015-02-04 17:58:19 +053036 super(ServersTestJSON, cls).setup_credentials()
37
38 @classmethod
39 def setup_clients(cls):
40 super(ServersTestJSON, cls).setup_clients()
41 cls.client = cls.servers_client
42 cls.network_client = cls.os.network_client
43
44 @classmethod
45 def resource_setup(cls):
Andrea Frittoli50bb80d2014-09-15 12:34:27 +010046 super(ServersTestJSON, cls).resource_setup()
Daryl Walleck6b9b2882012-04-08 21:43:39 -050047 cls.meta = {'hello': 'world'}
48 cls.accessIPv4 = '1.1.1.1'
Mauro S. M. Rodrigues54110362013-02-15 13:14:04 -050049 cls.accessIPv6 = '0000:0000:0000:0000:0000:babe:220.12.22.2'
Masayuki Igawa259c1132013-10-31 17:48:44 +090050 cls.name = data_utils.rand_name('server')
Daryl Walleck6b9b2882012-04-08 21:43:39 -050051 file_contents = 'This is a test file.'
Pádraig Bradyc6081cf2013-01-04 17:43:53 +000052 personality = [{'path': '/test.txt',
Daryl Walleck6b9b2882012-04-08 21:43:39 -050053 'contents': base64.b64encode(file_contents)}]
David Kranz0fb14292015-02-11 15:55:20 -050054 disk_config = cls.disk_config
55 cls.server_initial = cls.create_test_server(name=cls.name,
56 meta=cls.meta,
57 accessIPv4=cls.accessIPv4,
58 accessIPv6=cls.accessIPv6,
59 personality=personality,
60 disk_config=disk_config)
Daryl Walleck6b9b2882012-04-08 21:43:39 -050061 cls.password = cls.server_initial['adminPass']
62 cls.client.wait_for_server_status(cls.server_initial['id'], 'ACTIVE')
David Kranz0fb14292015-02-11 15:55:20 -050063 cls.server = cls.client.get_server(cls.server_initial['id'])
Daryl Walleck6b9b2882012-04-08 21:43:39 -050064
Masayuki Igawa209fd502014-02-17 14:46:43 +090065 @test.attr(type='smoke')
Chris Hoge7579c1a2015-02-26 14:12:15 -080066 @test.idempotent_id('5de47127-9977-400a-936f-abcfbec1218f')
Daryl Wallecked97dca2012-07-04 23:25:45 -050067 def test_verify_server_details(self):
Sean Dague4dd2c0b2013-01-03 17:50:28 -050068 # Verify the specified server attributes are set correctly
Daryl Walleck6b9b2882012-04-08 21:43:39 -050069 self.assertEqual(self.accessIPv4, self.server['accessIPv4'])
Mauro S. M. Rodrigues54110362013-02-15 13:14:04 -050070 # NOTE(maurosr): See http://tools.ietf.org/html/rfc5952 (section 4)
71 # Here we compare directly with the canonicalized format.
72 self.assertEqual(self.server['accessIPv6'],
73 str(netaddr.IPAddress(self.accessIPv6)))
Daryl Walleck6b9b2882012-04-08 21:43:39 -050074 self.assertEqual(self.name, self.server['name'])
75 self.assertEqual(self.image_ref, self.server['image']['id'])
Ken'ichi Ohmichi35772602013-11-14 15:03:27 +090076 self.assertEqual(self.flavor_ref, self.server['flavor']['id'])
Daryl Walleck6b9b2882012-04-08 21:43:39 -050077 self.assertEqual(self.meta, self.server['metadata'])
78
Masayuki Igawa209fd502014-02-17 14:46:43 +090079 @test.attr(type='smoke')
Chris Hoge7579c1a2015-02-26 14:12:15 -080080 @test.idempotent_id('9a438d88-10c6-4bcd-8b5b-5b6e25e1346f')
Daryl Wallecked97dca2012-07-04 23:25:45 -050081 def test_list_servers(self):
Sean Dague4dd2c0b2013-01-03 17:50:28 -050082 # The created server should be in the list of all servers
David Kranzae99b9a2015-02-16 13:37:01 -050083 body = self.client.list_servers()
Daryl Wallecked97dca2012-07-04 23:25:45 -050084 servers = body['servers']
85 found = any([i for i in servers if i['id'] == self.server['id']])
86 self.assertTrue(found)
87
Masayuki Igawa209fd502014-02-17 14:46:43 +090088 @test.attr(type='smoke')
Chris Hoge7579c1a2015-02-26 14:12:15 -080089 @test.idempotent_id('585e934c-448e-43c4-acbf-d06a9b899997')
Daryl Wallecked97dca2012-07-04 23:25:45 -050090 def test_list_servers_with_detail(self):
Sean Dague4dd2c0b2013-01-03 17:50:28 -050091 # The created server should be in the detailed list of all servers
David Kranzae99b9a2015-02-16 13:37:01 -050092 body = self.client.list_servers_with_detail()
Daryl Wallecked97dca2012-07-04 23:25:45 -050093 servers = body['servers']
94 found = any([i for i in servers if i['id'] == self.server['id']])
95 self.assertTrue(found)
96
Chris Hoge7579c1a2015-02-26 14:12:15 -080097 @test.idempotent_id('cbc0f52f-05aa-492b-bdc1-84b575ca294b')
Matt Riedemann6c668202014-03-24 09:17:10 -070098 @testtools.skipUnless(CONF.compute.run_ssh,
99 'Instance validation tests are disabled.')
Masayuki Igawa209fd502014-02-17 14:46:43 +0900100 @test.attr(type='gate')
Daryl Walleck6b9b2882012-04-08 21:43:39 -0500101 def test_verify_created_server_vcpus(self):
Sean Dague4dd2c0b2013-01-03 17:50:28 -0500102 # Verify that the number of vcpus reported by the instance matches
103 # the amount stated by the flavor
David Kranz2fa77b22015-02-09 11:39:50 -0500104 flavor = self.flavors_client.get_flavor_details(self.flavor_ref)
Masayuki Igawa209fd502014-02-17 14:46:43 +0900105 linux_client = remote_client.RemoteClient(self.server, self.ssh_user,
106 self.password)
Daryl Walleck6b9b2882012-04-08 21:43:39 -0500107 self.assertEqual(flavor['vcpus'], linux_client.get_number_of_vcpus())
108
Chris Hoge7579c1a2015-02-26 14:12:15 -0800109 @test.idempotent_id('ac1ad47f-984b-4441-9274-c9079b7a0666')
Matt Riedemann6c668202014-03-24 09:17:10 -0700110 @testtools.skipUnless(CONF.compute.run_ssh,
111 'Instance validation tests are disabled.')
Masayuki Igawa209fd502014-02-17 14:46:43 +0900112 @test.attr(type='gate')
Daryl Walleck6b9b2882012-04-08 21:43:39 -0500113 def test_host_name_is_same_as_server_name(self):
Sean Dague4dd2c0b2013-01-03 17:50:28 -0500114 # Verify the instance host name is the same as the server name
Masayuki Igawa209fd502014-02-17 14:46:43 +0900115 linux_client = remote_client.RemoteClient(self.server, self.ssh_user,
116 self.password)
Daryl Walleck6b9b2882012-04-08 21:43:39 -0500117 self.assertTrue(linux_client.hostname_equals_servername(self.name))
Dan Smith4307f992012-08-16 09:23:20 -0700118
Ken'ichi Ohmichi60a67f72014-05-20 09:19:50 +0900119 @test.attr(type='gate')
Chris Hoge7579c1a2015-02-26 14:12:15 -0800120 @test.idempotent_id('ed20d3fb-9d1f-4329-b160-543fbd5d9811')
Ken'ichi Ohmichi60a67f72014-05-20 09:19:50 +0900121 def test_create_server_with_scheduler_hint_group(self):
122 # Create a server with the scheduler hint "group".
123 name = data_utils.rand_name('server_group')
124 policies = ['affinity']
David Kranzae99b9a2015-02-16 13:37:01 -0500125 body = self.client.create_server_group(name=name,
126 policies=policies)
Ken'ichi Ohmichi60a67f72014-05-20 09:19:50 +0900127 group_id = body['id']
128 self.addCleanup(self.client.delete_server_group, group_id)
129
130 hints = {'group': group_id}
David Kranz0fb14292015-02-11 15:55:20 -0500131 server = self.create_test_server(sched_hints=hints,
132 wait_until='ACTIVE')
Ken'ichi Ohmichi60a67f72014-05-20 09:19:50 +0900133
134 # Check a server is in the group
David Kranzae99b9a2015-02-16 13:37:01 -0500135 server_group = self.client.get_server_group(group_id)
Ken'ichi Ohmichi60a67f72014-05-20 09:19:50 +0900136 self.assertIn(server['id'], server_group['members'])
137
Chris Hoge7579c1a2015-02-26 14:12:15 -0800138 @test.idempotent_id('0578d144-ed74-43f8-8e57-ab10dbf9b3c2')
Joseph Lanoux38edc052014-09-18 14:25:46 +0000139 @testtools.skipUnless(CONF.service_available.neutron,
140 'Neutron service must be available.')
141 def test_verify_multiple_nics_order(self):
142 # Verify that the networks order given at the server creation is
143 # preserved within the server.
144 name_net1 = data_utils.rand_name(self.__class__.__name__)
David Kranz34e88122014-12-11 15:24:05 -0500145 net1 = self.network_client.create_network(name=name_net1)
Joseph Lanouxe59f0ff2014-10-17 14:56:56 +0000146 self.addCleanup(self.network_client.delete_network,
147 net1['network']['id'])
148
Joseph Lanoux38edc052014-09-18 14:25:46 +0000149 name_net2 = data_utils.rand_name(self.__class__.__name__)
David Kranz34e88122014-12-11 15:24:05 -0500150 net2 = self.network_client.create_network(name=name_net2)
Joseph Lanouxe59f0ff2014-10-17 14:56:56 +0000151 self.addCleanup(self.network_client.delete_network,
152 net2['network']['id'])
Joseph Lanoux38edc052014-09-18 14:25:46 +0000153
David Kranz34e88122014-12-11 15:24:05 -0500154 subnet1 = self.network_client.create_subnet(
Joseph Lanoux38edc052014-09-18 14:25:46 +0000155 network_id=net1['network']['id'],
156 cidr='19.80.0.0/24',
157 ip_version=4)
Joseph Lanouxe59f0ff2014-10-17 14:56:56 +0000158 self.addCleanup(self.network_client.delete_subnet,
159 subnet1['subnet']['id'])
160
David Kranz34e88122014-12-11 15:24:05 -0500161 subnet2 = self.network_client.create_subnet(
Joseph Lanoux38edc052014-09-18 14:25:46 +0000162 network_id=net2['network']['id'],
163 cidr='19.86.0.0/24',
164 ip_version=4)
Joseph Lanouxe59f0ff2014-10-17 14:56:56 +0000165 self.addCleanup(self.network_client.delete_subnet,
166 subnet2['subnet']['id'])
Joseph Lanoux38edc052014-09-18 14:25:46 +0000167
168 networks = [{'uuid': net1['network']['id']},
169 {'uuid': net2['network']['id']}]
170
David Kranz0fb14292015-02-11 15:55:20 -0500171 server_multi_nics = self.create_test_server(
Joseph Lanoux38edc052014-09-18 14:25:46 +0000172 networks=networks, wait_until='ACTIVE')
173
Joseph Lanouxe59f0ff2014-10-17 14:56:56 +0000174 # Cleanup server; this is needed in the test case because with the LIFO
175 # nature of the cleanups, if we don't delete the server first, the port
176 # will still be part of the subnet and we'll get a 409 from Neutron
177 # when trying to delete the subnet. The tear down in the base class
178 # will try to delete the server and get a 404 but it's ignored so
179 # we're OK.
180 def cleanup_server():
181 self.client.delete_server(server_multi_nics['id'])
182 self.client.wait_for_server_termination(server_multi_nics['id'])
183
184 self.addCleanup(cleanup_server)
185
David Kranzae99b9a2015-02-16 13:37:01 -0500186 addresses = self.client.list_addresses(server_multi_nics['id'])
Joseph Lanoux38edc052014-09-18 14:25:46 +0000187
venkata anilbd2d49a2015-01-16 08:07:15 +0000188 # We can't predict the ip addresses assigned to the server on networks.
189 # Sometimes the assigned addresses are ['19.80.0.2', '19.86.0.2'], at
190 # other times ['19.80.0.3', '19.86.0.3']. So we check if the first
191 # address is in first network, similarly second address is in second
192 # network.
Joseph Lanoux38edc052014-09-18 14:25:46 +0000193 addr = [addresses[name_net1][0]['addr'],
194 addresses[name_net2][0]['addr']]
venkata anilbd2d49a2015-01-16 08:07:15 +0000195 networks = [netaddr.IPNetwork('19.80.0.0/24'),
196 netaddr.IPNetwork('19.86.0.0/24')]
197 for address, network in zip(addr, networks):
198 self.assertIn(address, network)
Joseph Lanoux38edc052014-09-18 14:25:46 +0000199
Dan Smith4307f992012-08-16 09:23:20 -0700200
Chang Bo Guoedd6ec02013-12-12 23:53:09 -0800201class ServersWithSpecificFlavorTestJSON(base.BaseV2ComputeAdminTest):
Chang Bo Guoedd6ec02013-12-12 23:53:09 -0800202 disk_config = 'AUTO'
203
204 @classmethod
Rohan Kanade60b73092015-02-04 17:58:19 +0530205 def setup_clients(cls):
Attila Fazekas423834d2014-03-14 17:33:13 +0100206 cls.prepare_instance_network()
Rohan Kanade60b73092015-02-04 17:58:19 +0530207 super(ServersWithSpecificFlavorTestJSON, cls).setup_clients()
Chang Bo Guoedd6ec02013-12-12 23:53:09 -0800208 cls.flavor_client = cls.os_adm.flavors_client
Attila Fazekas076f79f2014-03-14 17:43:46 +0100209 cls.client = cls.servers_client
Chang Bo Guoedd6ec02013-12-12 23:53:09 -0800210
Chris Hoge7579c1a2015-02-26 14:12:15 -0800211 @test.idempotent_id('b3c7bcfc-bb5b-4e22-b517-c7f686b802ca')
Matt Riedemann6c668202014-03-24 09:17:10 -0700212 @testtools.skipUnless(CONF.compute.run_ssh,
213 'Instance validation tests are disabled.')
Masayuki Igawa209fd502014-02-17 14:46:43 +0900214 @test.attr(type='gate')
Chang Bo Guoedd6ec02013-12-12 23:53:09 -0800215 def test_verify_created_server_ephemeral_disk(self):
216 # Verify that the ephemeral disk is created when creating server
217
Attila Fazekas076f79f2014-03-14 17:43:46 +0100218 def create_flavor_with_extra_specs():
Chang Bo Guoedd6ec02013-12-12 23:53:09 -0800219 flavor_with_eph_disk_name = data_utils.rand_name('eph_flavor')
220 flavor_with_eph_disk_id = data_utils.rand_int_id(start=1000)
221 ram = 64
222 vcpus = 1
223 disk = 0
224
225 # Create a flavor with extra specs
David Kranz2fa77b22015-02-09 11:39:50 -0500226 flavor = (self.flavor_client.
227 create_flavor(flavor_with_eph_disk_name,
228 ram, vcpus, disk,
229 flavor_with_eph_disk_id,
230 ephemeral=1))
Attila Fazekas076f79f2014-03-14 17:43:46 +0100231 self.addCleanup(flavor_clean_up, flavor['id'])
Chang Bo Guoedd6ec02013-12-12 23:53:09 -0800232
233 return flavor['id']
234
Attila Fazekas076f79f2014-03-14 17:43:46 +0100235 def create_flavor_without_extra_specs():
Chang Bo Guoedd6ec02013-12-12 23:53:09 -0800236 flavor_no_eph_disk_name = data_utils.rand_name('no_eph_flavor')
237 flavor_no_eph_disk_id = data_utils.rand_int_id(start=1000)
238
239 ram = 64
240 vcpus = 1
241 disk = 0
242
243 # Create a flavor without extra specs
David Kranz2fa77b22015-02-09 11:39:50 -0500244 flavor = (self.flavor_client.
245 create_flavor(flavor_no_eph_disk_name,
246 ram, vcpus, disk,
247 flavor_no_eph_disk_id))
Attila Fazekas076f79f2014-03-14 17:43:46 +0100248 self.addCleanup(flavor_clean_up, flavor['id'])
Chang Bo Guoedd6ec02013-12-12 23:53:09 -0800249
250 return flavor['id']
251
Attila Fazekas076f79f2014-03-14 17:43:46 +0100252 def flavor_clean_up(flavor_id):
David Kranz2fa77b22015-02-09 11:39:50 -0500253 self.flavor_client.delete_flavor(flavor_id)
Chang Bo Guoedd6ec02013-12-12 23:53:09 -0800254 self.flavor_client.wait_for_resource_deletion(flavor_id)
255
Attila Fazekas076f79f2014-03-14 17:43:46 +0100256 flavor_with_eph_disk_id = create_flavor_with_extra_specs()
257 flavor_no_eph_disk_id = create_flavor_without_extra_specs()
Chang Bo Guoedd6ec02013-12-12 23:53:09 -0800258
259 admin_pass = self.image_ssh_password
260
David Kranz0fb14292015-02-11 15:55:20 -0500261 server_no_eph_disk = (self.create_test_server(
262 wait_until='ACTIVE',
263 adminPass=admin_pass,
264 flavor=flavor_no_eph_disk_id))
265 server_with_eph_disk = (self.create_test_server(
266 wait_until='ACTIVE',
267 adminPass=admin_pass,
268 flavor=flavor_with_eph_disk_id))
Chang Bo Guoedd6ec02013-12-12 23:53:09 -0800269 # Get partition number of server without extra specs.
David Kranz0fb14292015-02-11 15:55:20 -0500270 server_no_eph_disk = self.client.get_server(
Attila Fazekas076f79f2014-03-14 17:43:46 +0100271 server_no_eph_disk['id'])
Masayuki Igawa209fd502014-02-17 14:46:43 +0900272 linux_client = remote_client.RemoteClient(server_no_eph_disk,
Attila Fazekas076f79f2014-03-14 17:43:46 +0100273 self.ssh_user, admin_pass)
274 partition_num = len(linux_client.get_partitions().split('\n'))
Chang Bo Guoedd6ec02013-12-12 23:53:09 -0800275
David Kranz0fb14292015-02-11 15:55:20 -0500276 server_with_eph_disk = self.client.get_server(
Attila Fazekas076f79f2014-03-14 17:43:46 +0100277 server_with_eph_disk['id'])
Masayuki Igawa209fd502014-02-17 14:46:43 +0900278 linux_client = remote_client.RemoteClient(server_with_eph_disk,
Attila Fazekas076f79f2014-03-14 17:43:46 +0100279 self.ssh_user, admin_pass)
280 partition_num_emph = len(linux_client.get_partitions().split('\n'))
281 self.assertEqual(partition_num + 1, partition_num_emph)
Chang Bo Guoedd6ec02013-12-12 23:53:09 -0800282
283
Attila Fazekas19044d52013-02-16 07:35:06 +0100284class ServersTestManualDisk(ServersTestJSON):
285 disk_config = 'MANUAL'
286
Daryl Walleck0aea0032012-12-04 00:53:28 -0600287 @classmethod
Rohan Kanade60b73092015-02-04 17:58:19 +0530288 def skip_checks(cls):
289 super(ServersTestManualDisk, cls).skip_checks()
Sean Dague86bd8422013-12-20 09:56:44 -0500290 if not CONF.compute_feature_enabled.disk_config:
Daryl Walleck0aea0032012-12-04 00:53:28 -0600291 msg = "DiskConfig extension not enabled."
ivan-zhu1feeb382013-01-24 10:14:39 +0800292 raise cls.skipException(msg)