blob: 54861be594a8732616d324c3497008230fee686b [file] [log] [blame]
ZhiQiang Fan39f97222013-09-20 04:49:44 +08001# Copyright 2012 OpenStack Foundation
Attila Fazekasa23f5002012-10-23 19:32:45 +02002# 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
Attila Fazekas234d3e82013-02-22 16:39:49 +010016from boto import exception
Matthew Treinisha83a16e2012-12-07 13:44:02 -050017
Masayuki Igawa259c1132013-10-31 17:48:44 +090018from tempest.common.utils import data_utils
Matthew Treinisha83a16e2012-12-07 13:44:02 -050019from tempest.common.utils.linux.remote_client import RemoteClient
Matthew Treinish88f49ef2014-01-29 18:36:27 +000020from tempest import config
Attila Fazekas234d3e82013-02-22 16:39:49 +010021from tempest import exceptions
Matthew Treinishf4a9b0f2013-07-26 16:58:26 -040022from tempest.openstack.common import log as logging
Chris Yeoh01cb2792013-02-09 22:25:37 +103023from tempest.test import attr
Giulio Fidente83181a92013-10-01 06:02:24 +020024from tempest.test import skip_because
Sean Dague09761f62013-05-13 15:20:40 -040025from tempest.thirdparty.boto.test import BotoTestCase
26from tempest.thirdparty.boto.utils.s3 import s3_upload_dir
27from tempest.thirdparty.boto.utils.wait import re_search_wait
28from tempest.thirdparty.boto.utils.wait import state_wait
Attila Fazekasa23f5002012-10-23 19:32:45 +020029
Matthew Treinish88f49ef2014-01-29 18:36:27 +000030CONF = config.CONF
31
Attila Fazekasa23f5002012-10-23 19:32:45 +020032LOG = logging.getLogger(__name__)
33
34
Attila Fazekasa23f5002012-10-23 19:32:45 +020035class InstanceRunTest(BotoTestCase):
36
37 @classmethod
38 def setUpClass(cls):
39 super(InstanceRunTest, cls).setUpClass()
Attila Fazekas234d3e82013-02-22 16:39:49 +010040 if not cls.conclusion['A_I_IMAGES_READY']:
ivan-zhu1feeb382013-01-24 10:14:39 +080041 raise cls.skipException("".join(("EC2 ", cls.__name__,
42 ": requires ami/aki/ari manifest")))
Attila Fazekasa23f5002012-10-23 19:32:45 +020043 cls.s3_client = cls.os.s3_client
44 cls.ec2_client = cls.os.ec2api_client
Attila Fazekasa23f5002012-10-23 19:32:45 +020045 cls.zone = cls.ec2_client.get_good_zone()
Matthew Treinish88f49ef2014-01-29 18:36:27 +000046 cls.materials_path = CONF.boto.s3_materials_path
47 ami_manifest = CONF.boto.ami_manifest
48 aki_manifest = CONF.boto.aki_manifest
49 ari_manifest = CONF.boto.ari_manifest
50 cls.instance_type = CONF.boto.instance_type
Masayuki Igawa259c1132013-10-31 17:48:44 +090051 cls.bucket_name = data_utils.rand_name("s3bucket-")
52 cls.keypair_name = data_utils.rand_name("keypair-")
Attila Fazekasa23f5002012-10-23 19:32:45 +020053 cls.keypair = cls.ec2_client.create_key_pair(cls.keypair_name)
54 cls.addResourceCleanUp(cls.ec2_client.delete_key_pair,
55 cls.keypair_name)
56 bucket = cls.s3_client.create_bucket(cls.bucket_name)
57 cls.addResourceCleanUp(cls.destroy_bucket,
58 cls.s3_client.connection_data,
59 cls.bucket_name)
60 s3_upload_dir(bucket, cls.materials_path)
61 cls.images = {"ami":
Masayuki Igawa259c1132013-10-31 17:48:44 +090062 {"name": data_utils.rand_name("ami-name-"),
Attila Fazekasa23f5002012-10-23 19:32:45 +020063 "location": cls.bucket_name + "/" + ami_manifest},
64 "aki":
Masayuki Igawa259c1132013-10-31 17:48:44 +090065 {"name": data_utils.rand_name("aki-name-"),
Attila Fazekasa23f5002012-10-23 19:32:45 +020066 "location": cls.bucket_name + "/" + aki_manifest},
67 "ari":
Masayuki Igawa259c1132013-10-31 17:48:44 +090068 {"name": data_utils.rand_name("ari-name-"),
Attila Fazekasa23f5002012-10-23 19:32:45 +020069 "location": cls.bucket_name + "/" + ari_manifest}}
70 for image in cls.images.itervalues():
71 image["image_id"] = cls.ec2_client.register_image(
Sean Dague14c68182013-04-14 15:34:30 -040072 name=image["name"],
73 image_location=image["location"])
Attila Fazekasa23f5002012-10-23 19:32:45 +020074 cls.addResourceCleanUp(cls.ec2_client.deregister_image,
75 image["image_id"])
76
77 for image in cls.images.itervalues():
78 def _state():
79 retr = cls.ec2_client.get_image(image["image_id"])
80 return retr.state
81 state = state_wait(_state, "available")
82 if state != "available":
83 for _image in cls.images.itervalues():
Attila Fazekasfa756cb2013-02-12 10:52:42 +010084 cls.ec2_client.deregister_image(_image["image_id"])
Attila Fazekas234d3e82013-02-22 16:39:49 +010085 raise exceptions.EC2RegisterImageException(image_id=
86 image["image_id"])
Attila Fazekasa23f5002012-10-23 19:32:45 +020087
88 @attr(type='smoke')
Burt Holzmanf70f2222013-07-18 23:36:31 -050089 def test_run_idempotent_instances(self):
90 # EC2 run instances idempotently
91
92 def _run_instance(client_token):
93 reservation = self.ec2_client.run_instances(
94 image_id=self.images["ami"]["image_id"],
95 kernel_id=self.images["aki"]["image_id"],
96 ramdisk_id=self.images["ari"]["image_id"],
97 instance_type=self.instance_type,
98 client_token=client_token)
99 rcuk = self.addResourceCleanUp(self.destroy_reservation,
100 reservation)
101 return (reservation, rcuk)
102
103 def _terminate_reservation(reservation, rcuk):
104 for instance in reservation.instances:
105 instance.terminate()
106 self.cancelResourceCleanUp(rcuk)
107
108 reservation_1, rcuk_1 = _run_instance('token_1')
109 reservation_2, rcuk_2 = _run_instance('token_2')
110 reservation_1a, rcuk_1a = _run_instance('token_1')
111
112 self.assertIsNotNone(reservation_1)
113 self.assertIsNotNone(reservation_2)
114 self.assertIsNotNone(reservation_1a)
115
116 # same reservation for token_1
117 self.assertEqual(reservation_1.id, reservation_1a.id)
118
119 # Cancel cleanup -- since it's a duplicate, it's
120 # handled by rcuk1
121 self.cancelResourceCleanUp(rcuk_1a)
122
123 _terminate_reservation(reservation_1, rcuk_1)
124 _terminate_reservation(reservation_2, rcuk_2)
125
Burt Holzmanf70f2222013-07-18 23:36:31 -0500126 @attr(type='smoke')
Attila Fazekasa23f5002012-10-23 19:32:45 +0200127 def test_run_stop_terminate_instance(self):
Sean Dague64ef48d2013-01-03 17:54:36 -0500128 # EC2 run, stop and terminate instance
Attila Fazekasa23f5002012-10-23 19:32:45 +0200129 image_ami = self.ec2_client.get_image(self.images["ami"]
130 ["image_id"])
131 reservation = image_ami.run(kernel_id=self.images["aki"]["image_id"],
132 ramdisk_id=self.images["ari"]["image_id"],
133 instance_type=self.instance_type)
134 rcuk = self.addResourceCleanUp(self.destroy_reservation, reservation)
135
Attila Fazekasa23f5002012-10-23 19:32:45 +0200136 for instance in reservation.instances:
137 LOG.info("state: %s", instance.state)
138 if instance.state != "running":
Attila Fazekas40aa3612013-01-19 22:16:38 +0100139 self.assertInstanceStateWait(instance, "running")
Attila Fazekasa23f5002012-10-23 19:32:45 +0200140
141 for instance in reservation.instances:
142 instance.stop()
143 LOG.info("state: %s", instance.state)
144 if instance.state != "stopped":
Attila Fazekas40aa3612013-01-19 22:16:38 +0100145 self.assertInstanceStateWait(instance, "stopped")
Attila Fazekasa23f5002012-10-23 19:32:45 +0200146
147 for instance in reservation.instances:
148 instance.terminate()
149 self.cancelResourceCleanUp(rcuk)
150
151 @attr(type='smoke')
Burt Holzmanbb575e12013-07-14 00:23:30 -0500152 def test_run_stop_terminate_instance_with_tags(self):
153 # EC2 run, stop and terminate instance with tags
154 image_ami = self.ec2_client.get_image(self.images["ami"]
155 ["image_id"])
156 reservation = image_ami.run(kernel_id=self.images["aki"]["image_id"],
157 ramdisk_id=self.images["ari"]["image_id"],
158 instance_type=self.instance_type)
159 rcuk = self.addResourceCleanUp(self.destroy_reservation, reservation)
160
161 for instance in reservation.instances:
162 LOG.info("state: %s", instance.state)
163 if instance.state != "running":
164 self.assertInstanceStateWait(instance, "running")
165 instance.add_tag('key1', value='value1')
166
167 tags = self.ec2_client.get_all_tags()
Chang Bo Guofc77e932013-09-16 17:38:26 -0700168 self.assertEqual(tags[0].name, 'key1')
169 self.assertEqual(tags[0].value, 'value1')
Burt Holzmanbb575e12013-07-14 00:23:30 -0500170
171 tags = self.ec2_client.get_all_tags(filters={'key': 'key1'})
Chang Bo Guofc77e932013-09-16 17:38:26 -0700172 self.assertEqual(tags[0].name, 'key1')
173 self.assertEqual(tags[0].value, 'value1')
Burt Holzmanbb575e12013-07-14 00:23:30 -0500174
175 tags = self.ec2_client.get_all_tags(filters={'value': 'value1'})
Chang Bo Guofc77e932013-09-16 17:38:26 -0700176 self.assertEqual(tags[0].name, 'key1')
177 self.assertEqual(tags[0].value, 'value1')
Burt Holzmanbb575e12013-07-14 00:23:30 -0500178
179 tags = self.ec2_client.get_all_tags(filters={'key': 'value2'})
Attila Fazekas849708e2013-09-25 17:33:56 +0200180 self.assertEqual(len(tags), 0, str(tags))
Burt Holzmanbb575e12013-07-14 00:23:30 -0500181
182 for instance in reservation.instances:
183 instance.remove_tag('key1', value='value1')
184
185 tags = self.ec2_client.get_all_tags()
Attila Fazekas849708e2013-09-25 17:33:56 +0200186 self.assertEqual(len(tags), 0, str(tags))
Burt Holzmanbb575e12013-07-14 00:23:30 -0500187
188 for instance in reservation.instances:
189 instance.stop()
190 LOG.info("state: %s", instance.state)
191 if instance.state != "stopped":
192 self.assertInstanceStateWait(instance, "stopped")
193
194 for instance in reservation.instances:
195 instance.terminate()
196 self.cancelResourceCleanUp(rcuk)
197
Giulio Fidente83181a92013-10-01 06:02:24 +0200198 @skip_because(bug="1098891")
Burt Holzmanbb575e12013-07-14 00:23:30 -0500199 @attr(type='smoke')
Attila Fazekasa23f5002012-10-23 19:32:45 +0200200 def test_run_terminate_instance(self):
Sean Dague64ef48d2013-01-03 17:54:36 -0500201 # EC2 run, terminate immediately
Attila Fazekasa23f5002012-10-23 19:32:45 +0200202 image_ami = self.ec2_client.get_image(self.images["ami"]
203 ["image_id"])
204 reservation = image_ami.run(kernel_id=self.images["aki"]["image_id"],
205 ramdisk_id=self.images["ari"]["image_id"],
206 instance_type=self.instance_type)
207
208 for instance in reservation.instances:
209 instance.terminate()
Attila Fazekas37f83042013-01-12 16:13:03 +0100210 try:
211 instance.update(validate=True)
212 except ValueError:
213 pass
Attila Fazekas234d3e82013-02-22 16:39:49 +0100214 except exception.EC2ResponseError as exc:
Attila Fazekas37f83042013-01-12 16:13:03 +0100215 if self.ec2_error_code.\
216 client.InvalidInstanceID.NotFound.match(exc):
217 pass
218 else:
219 raise
220 else:
221 self.assertNotEqual(instance.state, "running")
Attila Fazekasa23f5002012-10-23 19:32:45 +0200222
Attila Fazekas3e381f72013-08-01 16:52:23 +0200223 # NOTE(afazekas): doctored test case,
Attila Fazekasa23f5002012-10-23 19:32:45 +0200224 # with normal validation it would fail
Giulio Fidente83181a92013-10-01 06:02:24 +0200225 @skip_because(bug="1182679")
Giampaolo Lauriacb9209d2013-05-17 13:39:25 -0400226 @attr(type='smoke')
Attila Fazekasa23f5002012-10-23 19:32:45 +0200227 def test_integration_1(self):
Sean Dague64ef48d2013-01-03 17:54:36 -0500228 # EC2 1. integration test (not strict)
Attila Fazekasa23f5002012-10-23 19:32:45 +0200229 image_ami = self.ec2_client.get_image(self.images["ami"]["image_id"])
Masayuki Igawa259c1132013-10-31 17:48:44 +0900230 sec_group_name = data_utils.rand_name("securitygroup-")
Attila Fazekasa23f5002012-10-23 19:32:45 +0200231 group_desc = sec_group_name + " security group description "
232 security_group = self.ec2_client.create_security_group(sec_group_name,
233 group_desc)
234 self.addResourceCleanUp(self.destroy_security_group_wait,
235 security_group)
Sean Dague14c68182013-04-14 15:34:30 -0400236 self.assertTrue(
237 self.ec2_client.authorize_security_group(
Chris Yeoh86732f92013-02-27 20:52:06 +1030238 sec_group_name,
239 ip_protocol="icmp",
240 cidr_ip="0.0.0.0/0",
241 from_port=-1,
242 to_port=-1))
Sean Dague14c68182013-04-14 15:34:30 -0400243 self.assertTrue(
244 self.ec2_client.authorize_security_group(
Chris Yeoh86732f92013-02-27 20:52:06 +1030245 sec_group_name,
246 ip_protocol="tcp",
247 cidr_ip="0.0.0.0/0",
248 from_port=22,
249 to_port=22))
Attila Fazekasa23f5002012-10-23 19:32:45 +0200250 reservation = image_ami.run(kernel_id=self.images["aki"]["image_id"],
251 ramdisk_id=self.images["ari"]["image_id"],
252 instance_type=self.instance_type,
253 key_name=self.keypair_name,
254 security_groups=(sec_group_name,))
255 self.addResourceCleanUp(self.destroy_reservation,
256 reservation)
257 volume = self.ec2_client.create_volume(1, self.zone)
258 self.addResourceCleanUp(self.destroy_volume_wait, volume)
259 instance = reservation.instances[0]
Attila Fazekasa23f5002012-10-23 19:32:45 +0200260 LOG.info("state: %s", instance.state)
261 if instance.state != "running":
Attila Fazekas40aa3612013-01-19 22:16:38 +0100262 self.assertInstanceStateWait(instance, "running")
Attila Fazekasa23f5002012-10-23 19:32:45 +0200263
264 address = self.ec2_client.allocate_address()
265 rcuk_a = self.addResourceCleanUp(address.delete)
Chris Yeoh86732f92013-02-27 20:52:06 +1030266 self.assertTrue(address.associate(instance.id))
Attila Fazekasa23f5002012-10-23 19:32:45 +0200267
268 rcuk_da = self.addResourceCleanUp(address.disassociate)
Attila Fazekas3e381f72013-08-01 16:52:23 +0200269 # TODO(afazekas): ping test. dependecy/permission ?
Attila Fazekasa23f5002012-10-23 19:32:45 +0200270
Attila Fazekas40aa3612013-01-19 22:16:38 +0100271 self.assertVolumeStatusWait(volume, "available")
Marc Solanasb15d8b62014-02-07 00:04:15 -0800272 # NOTE(afazekas): it may be reports available before it is available
Attila Fazekasa23f5002012-10-23 19:32:45 +0200273
274 ssh = RemoteClient(address.public_ip,
Matthew Treinish88f49ef2014-01-29 18:36:27 +0000275 CONF.compute.ssh_user,
Attila Fazekasa23f5002012-10-23 19:32:45 +0200276 pkey=self.keypair.material)
Masayuki Igawa259c1132013-10-31 17:48:44 +0900277 text = data_utils.rand_name("Pattern text for console output -")
Attila Fazekasa23f5002012-10-23 19:32:45 +0200278 resp = ssh.write_to_console(text)
279 self.assertFalse(resp)
280
281 def _output():
282 output = instance.get_console_output()
283 return output.output
284
285 re_search_wait(_output, text)
286 part_lines = ssh.get_partitions().split('\n')
Attila Fazekasa23f5002012-10-23 19:32:45 +0200287 volume.attach(instance.id, "/dev/vdh")
288
Attila Fazekas40aa3612013-01-19 22:16:38 +0100289 def _volume_state():
290 volume.update(validate=True)
291 return volume.status
292
Chris Yeohf2a5e822013-05-08 21:33:00 +0930293 self.assertVolumeStatusWait(_volume_state, "in-use")
Attila Fazekasa23f5002012-10-23 19:32:45 +0200294 re_search_wait(_volume_state, "in-use")
295
Attila Fazekas3e381f72013-08-01 16:52:23 +0200296 # NOTE(afazekas): Different Hypervisor backends names
Attila Fazekasa23f5002012-10-23 19:32:45 +0200297 # differently the devices,
298 # now we just test is the partition number increased/decrised
299
300 def _part_state():
301 current = ssh.get_partitions().split('\n')
302 if current > part_lines:
303 return 'INCREASE'
304 if current < part_lines:
305 return 'DECREASE'
306 return 'EQUAL'
307
308 state_wait(_part_state, 'INCREASE')
309 part_lines = ssh.get_partitions().split('\n')
310
Attila Fazekas3e381f72013-08-01 16:52:23 +0200311 # TODO(afazekas): Resource compare to the flavor settings
Attila Fazekasa23f5002012-10-23 19:32:45 +0200312
Chris Yeohf2a5e822013-05-08 21:33:00 +0930313 volume.detach()
Attila Fazekasa23f5002012-10-23 19:32:45 +0200314
Chris Yeohf2a5e822013-05-08 21:33:00 +0930315 self.assertVolumeStatusWait(_volume_state, "available")
Attila Fazekasa23f5002012-10-23 19:32:45 +0200316 re_search_wait(_volume_state, "available")
317 LOG.info("Volume %s state: %s", volume.id, volume.status)
318
319 state_wait(_part_state, 'DECREASE')
320
321 instance.stop()
322 address.disassociate()
323 self.assertAddressDissasociatedWait(address)
324 self.cancelResourceCleanUp(rcuk_da)
325 address.release()
326 self.assertAddressReleasedWait(address)
327 self.cancelResourceCleanUp(rcuk_a)
328
329 LOG.info("state: %s", instance.state)
330 if instance.state != "stopped":
Attila Fazekas40aa3612013-01-19 22:16:38 +0100331 self.assertInstanceStateWait(instance, "stopped")
Attila Fazekas3e381f72013-08-01 16:52:23 +0200332 # TODO(afazekas): move steps from teardown to the test case
Attila Fazekasa23f5002012-10-23 19:32:45 +0200333
334
Attila Fazekas3e381f72013-08-01 16:52:23 +0200335# TODO(afazekas): Snapshot/volume read/write test case