blob: 403ec4c81fca71e0da0940cc6de102fa45362814 [file] [log] [blame]
Attila Fazekasa23f5002012-10-23 19:32:45 +02001# vim: tabstop=4 shiftwidth=4 softtabstop=4
2
3# Copyright 2012 OpenStack, LLC
4# 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
Attila Fazekasa23f5002012-10-23 19:32:45 +020018import logging
19
Attila Fazekas37f83042013-01-12 16:13:03 +010020from boto.exception import EC2ResponseError
ivan-zhu1feeb382013-01-24 10:14:39 +080021import testtools
Matthew Treinisha83a16e2012-12-07 13:44:02 -050022
Matthew Treinish481466b2012-12-20 17:16:01 -050023from tempest import clients
Matthew Treinisha83a16e2012-12-07 13:44:02 -050024from tempest.common.utils.data_utils import rand_name
25from tempest.common.utils.linux.remote_client import RemoteClient
Chris Yeoh01cb2792013-02-09 22:25:37 +103026from tempest.test import attr
Matthew Treinisha83a16e2012-12-07 13:44:02 -050027from tempest.testboto import BotoTestCase
28import tempest.tests.boto
29from tempest.tests.boto.utils.s3 import s3_upload_dir
30from tempest.tests.boto.utils.wait import re_search_wait
31from tempest.tests.boto.utils.wait import state_wait
Attila Fazekasa23f5002012-10-23 19:32:45 +020032
33LOG = logging.getLogger(__name__)
34
35
36@attr("S3", "EC2")
37class InstanceRunTest(BotoTestCase):
38
39 @classmethod
40 def setUpClass(cls):
41 super(InstanceRunTest, cls).setUpClass()
42 if not tempest.tests.boto.A_I_IMAGES_READY:
ivan-zhu1feeb382013-01-24 10:14:39 +080043 raise cls.skipException("".join(("EC2 ", cls.__name__,
44 ": requires ami/aki/ari manifest")))
Matthew Treinish481466b2012-12-20 17:16:01 -050045 cls.os = clients.Manager()
Attila Fazekasa23f5002012-10-23 19:32:45 +020046 cls.s3_client = cls.os.s3_client
47 cls.ec2_client = cls.os.ec2api_client
48 config = cls.os.config
49 cls.zone = cls.ec2_client.get_good_zone()
50 cls.materials_path = config.boto.s3_materials_path
51 ami_manifest = config.boto.ami_manifest
52 aki_manifest = config.boto.aki_manifest
53 ari_manifest = config.boto.ari_manifest
54 cls.instance_type = config.boto.instance_type
55 cls.bucket_name = rand_name("s3bucket-")
56 cls.keypair_name = rand_name("keypair-")
57 cls.keypair = cls.ec2_client.create_key_pair(cls.keypair_name)
58 cls.addResourceCleanUp(cls.ec2_client.delete_key_pair,
59 cls.keypair_name)
60 bucket = cls.s3_client.create_bucket(cls.bucket_name)
61 cls.addResourceCleanUp(cls.destroy_bucket,
62 cls.s3_client.connection_data,
63 cls.bucket_name)
64 s3_upload_dir(bucket, cls.materials_path)
65 cls.images = {"ami":
66 {"name": rand_name("ami-name-"),
67 "location": cls.bucket_name + "/" + ami_manifest},
68 "aki":
69 {"name": rand_name("aki-name-"),
70 "location": cls.bucket_name + "/" + aki_manifest},
71 "ari":
72 {"name": rand_name("ari-name-"),
73 "location": cls.bucket_name + "/" + ari_manifest}}
74 for image in cls.images.itervalues():
75 image["image_id"] = cls.ec2_client.register_image(
76 name=image["name"],
77 image_location=image["location"])
78 cls.addResourceCleanUp(cls.ec2_client.deregister_image,
79 image["image_id"])
80
81 for image in cls.images.itervalues():
82 def _state():
83 retr = cls.ec2_client.get_image(image["image_id"])
84 return retr.state
85 state = state_wait(_state, "available")
86 if state != "available":
87 for _image in cls.images.itervalues():
Attila Fazekasfa756cb2013-02-12 10:52:42 +010088 cls.ec2_client.deregister_image(_image["image_id"])
89 raise EC2RegisterImageException(image_id=image["image_id"])
Attila Fazekasa23f5002012-10-23 19:32:45 +020090
91 @attr(type='smoke')
92 def test_run_stop_terminate_instance(self):
Sean Dague64ef48d2013-01-03 17:54:36 -050093 # EC2 run, stop and terminate instance
Attila Fazekasa23f5002012-10-23 19:32:45 +020094 image_ami = self.ec2_client.get_image(self.images["ami"]
95 ["image_id"])
96 reservation = image_ami.run(kernel_id=self.images["aki"]["image_id"],
97 ramdisk_id=self.images["ari"]["image_id"],
98 instance_type=self.instance_type)
99 rcuk = self.addResourceCleanUp(self.destroy_reservation, reservation)
100
101 def _state():
102 instance.update(validate=True)
103 return instance.state
104
105 for instance in reservation.instances:
106 LOG.info("state: %s", instance.state)
107 if instance.state != "running":
108 self.assertInstanceStateWait(_state, "running")
109
110 for instance in reservation.instances:
111 instance.stop()
112 LOG.info("state: %s", instance.state)
113 if instance.state != "stopped":
114 self.assertInstanceStateWait(_state, "stopped")
115
116 for instance in reservation.instances:
117 instance.terminate()
118 self.cancelResourceCleanUp(rcuk)
119
120 @attr(type='smoke')
ivan-zhu1feeb382013-01-24 10:14:39 +0800121 @testtools.skip("Skipped until the Bug #1098891 is resolved")
Attila Fazekasa23f5002012-10-23 19:32:45 +0200122 def test_run_terminate_instance(self):
Sean Dague64ef48d2013-01-03 17:54:36 -0500123 # EC2 run, terminate immediately
Attila Fazekasa23f5002012-10-23 19:32:45 +0200124 image_ami = self.ec2_client.get_image(self.images["ami"]
125 ["image_id"])
126 reservation = image_ami.run(kernel_id=self.images["aki"]["image_id"],
127 ramdisk_id=self.images["ari"]["image_id"],
128 instance_type=self.instance_type)
129
130 for instance in reservation.instances:
131 instance.terminate()
Attila Fazekas37f83042013-01-12 16:13:03 +0100132 try:
133 instance.update(validate=True)
134 except ValueError:
135 pass
136 except EC2ResponseError as exc:
137 if self.ec2_error_code.\
138 client.InvalidInstanceID.NotFound.match(exc):
139 pass
140 else:
141 raise
142 else:
143 self.assertNotEqual(instance.state, "running")
Attila Fazekasa23f5002012-10-23 19:32:45 +0200144
145 #NOTE(afazekas): doctored test case,
146 # with normal validation it would fail
147 @attr("slow", type='smoke')
148 def test_integration_1(self):
Sean Dague64ef48d2013-01-03 17:54:36 -0500149 # EC2 1. integration test (not strict)
Attila Fazekasa23f5002012-10-23 19:32:45 +0200150 image_ami = self.ec2_client.get_image(self.images["ami"]["image_id"])
151 sec_group_name = rand_name("securitygroup-")
152 group_desc = sec_group_name + " security group description "
153 security_group = self.ec2_client.create_security_group(sec_group_name,
154 group_desc)
155 self.addResourceCleanUp(self.destroy_security_group_wait,
156 security_group)
157 self.ec2_client.authorize_security_group(sec_group_name,
158 ip_protocol="icmp",
159 cidr_ip="0.0.0.0/0",
160 from_port=-1,
161 to_port=-1)
162 self.ec2_client.authorize_security_group(sec_group_name,
163 ip_protocol="tcp",
164 cidr_ip="0.0.0.0/0",
165 from_port=22,
166 to_port=22)
167 reservation = image_ami.run(kernel_id=self.images["aki"]["image_id"],
168 ramdisk_id=self.images["ari"]["image_id"],
169 instance_type=self.instance_type,
170 key_name=self.keypair_name,
171 security_groups=(sec_group_name,))
172 self.addResourceCleanUp(self.destroy_reservation,
173 reservation)
174 volume = self.ec2_client.create_volume(1, self.zone)
175 self.addResourceCleanUp(self.destroy_volume_wait, volume)
176 instance = reservation.instances[0]
177
178 def _instance_state():
179 instance.update(validate=True)
180 return instance.state
181
182 def _volume_state():
183 volume.update(validate=True)
184 return volume.status
185
186 LOG.info("state: %s", instance.state)
187 if instance.state != "running":
188 self.assertInstanceStateWait(_instance_state, "running")
189
190 address = self.ec2_client.allocate_address()
191 rcuk_a = self.addResourceCleanUp(address.delete)
192 address.associate(instance.id)
193
194 rcuk_da = self.addResourceCleanUp(address.disassociate)
195 #TODO(afazekas): ping test. dependecy/permission ?
196
197 self.assertVolumeStatusWait(_volume_state, "available")
198 #NOTE(afazekas): it may be reports availble before it is available
199
200 ssh = RemoteClient(address.public_ip,
201 self.os.config.compute.ssh_user,
202 pkey=self.keypair.material)
203 text = rand_name("Pattern text for console output -")
204 resp = ssh.write_to_console(text)
205 self.assertFalse(resp)
206
207 def _output():
208 output = instance.get_console_output()
209 return output.output
210
211 re_search_wait(_output, text)
212 part_lines = ssh.get_partitions().split('\n')
213 # "attaching" invalid EC2 state ! #1074901
214 volume.attach(instance.id, "/dev/vdh")
215
216 #self.assertVolumeStatusWait(_volume_state, "in-use") # #1074901
217 re_search_wait(_volume_state, "in-use")
218
219 #NOTE(afazekas): Different Hypervisor backends names
220 # differently the devices,
221 # now we just test is the partition number increased/decrised
222
223 def _part_state():
224 current = ssh.get_partitions().split('\n')
225 if current > part_lines:
226 return 'INCREASE'
227 if current < part_lines:
228 return 'DECREASE'
229 return 'EQUAL'
230
231 state_wait(_part_state, 'INCREASE')
232 part_lines = ssh.get_partitions().split('\n')
233
234 #TODO(afazekas): Resource compare to the flavor settings
235
236 volume.detach() # "detaching" invalid EC2 status #1074901
237
238 #self.assertVolumeStatusWait(_volume_state, "available")
239 re_search_wait(_volume_state, "available")
240 LOG.info("Volume %s state: %s", volume.id, volume.status)
241
242 state_wait(_part_state, 'DECREASE')
243
244 instance.stop()
245 address.disassociate()
246 self.assertAddressDissasociatedWait(address)
247 self.cancelResourceCleanUp(rcuk_da)
248 address.release()
249 self.assertAddressReleasedWait(address)
250 self.cancelResourceCleanUp(rcuk_a)
251
252 LOG.info("state: %s", instance.state)
253 if instance.state != "stopped":
254 self.assertInstanceStateWait(_instance_state, "stopped")
255 #TODO(afazekas): move steps from teardown to the test case
256
257
258#TODO(afazekas): Snapshot/volume read/write test case