Merge lp:~zulcss/uec-testing-scripts/uec-testing-scripts into lp:uec-testing-scripts

Proposed by Chuck Short
Status: Merged
Approved by: C de-Avillez
Approved revision: 64
Merge reported by: C de-Avillez
Merged at revision: not available
Proposed branch: lp:~zulcss/uec-testing-scripts/uec-testing-scripts
Merge into: lp:uec-testing-scripts
Diff against target: 510 lines (+461/-0)
5 files modified
openstack/config.yaml (+5/-0)
openstack/uec_testing.py (+22/-0)
openstack/uectesting/base.py (+116/-0)
openstack/uectesting/testing.py (+312/-0)
openstack/uectesting/utils.py (+6/-0)
To merge this branch: bzr merge lp:~zulcss/uec-testing-scripts/uec-testing-scripts
Reviewer Review Type Date Requested Status
C de-Avillez (community) Approve
Review via email: mp+46058@code.launchpad.net

Description of the change

This branch breaks up openstack and uec.

To post a comment you must log in.
Revision history for this message
C de-Avillez (hggdh2) wrote :

approved.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added directory 'openstack'
2=== added directory 'openstack/bin'
3=== added file 'openstack/config.yaml'
4--- openstack/config.yaml 1970-01-01 00:00:00 +0000
5+++ openstack/config.yaml 2011-01-13 00:51:02 +0000
6@@ -0,0 +1,5 @@
7+conf:
8+ kernel_image: ~/tmp/natty-server-uec-i386-vmlinuz-virtual
9+ kernel_name: natty-server-uec-i386-vmlinuz-virtual
10+ image: ~/tmp/natty-server-uec-i386.img
11+ image_name: natty-server-uec-i386.img
12
13=== added file 'openstack/uec_testing.py'
14--- openstack/uec_testing.py 1970-01-01 00:00:00 +0000
15+++ openstack/uec_testing.py 2011-01-13 00:51:02 +0000
16@@ -0,0 +1,22 @@
17+#!/usr/bin/python
18+
19+import optparse
20+import yaml
21+import sys
22+import unittest
23+
24+from uectesting.utils import options
25+from uectesting.testing import UECImageTest, UECInstanceTest, UECVolumeTest
26+
27+def main():
28+ if options.config_file:
29+ suite = unittest.TestSuite()
30+ suite.addTest(unittest.makeSuite(UECImageTest))
31+ suite.addTest(unittest.makeSuite(UECInstanceTest))
32+ suite.addTest(unittest.makeSuite(UECVolumeTest))
33+
34+ unittest.TextTestRunner(verbosity=2).run(suite)
35+
36+
37+if __name__ == "__main__":
38+ main()
39
40=== added directory 'openstack/uectesting'
41=== added file 'openstack/uectesting/__init__.py'
42=== added file 'openstack/uectesting/base.py'
43--- openstack/uectesting/base.py 1970-01-01 00:00:00 +0000
44+++ openstack/uectesting/base.py 2011-01-13 00:51:02 +0000
45@@ -0,0 +1,116 @@
46+import boto
47+import commands
48+import httplib
49+import os
50+import paramiko
51+import random
52+import sys
53+import unittest
54+import yaml
55+
56+from boto.ec2.regioninfo import RegionInfo
57+from uectesting.utils import options
58+
59+class UECTestCase(unittest.TestCase):
60+ def connect_ssh(self, ip, key_name):
61+ # TODO(devcamcar): set a more reasonable connection timeout time
62+ key = paramiko.RSAKey.from_private_key_file('/tmp/%s.pem' % key_name)
63+ client = paramiko.SSHClient()
64+ client.set_missing_host_key_policy(paramiko.WarningPolicy())
65+ client.connect(ip, username='root', pkey=key)
66+ stdin, stdout, stderr = client.exec_command('uptime')
67+ print 'uptime: ', stdout.read()
68+ return client
69+
70+ def can_ping(self, ip):
71+ """ Attempt to ping the specified IP, and give up after 1 second. """
72+
73+ # NOTE(devcamcar): ping timeout flag is different in OSX.
74+ if sys.platform == 'darwin':
75+ timeout_flag = 't'
76+ else:
77+ timeout_flag = 'w'
78+
79+ status, output = commands.getstatusoutput('ping -c1 -%s1 %s' %
80+ (timeout_flag, ip))
81+ return status == 0
82+
83+ def get_connection(self, **kwargs):
84+ """
85+ Returns a boto ec2 connection for the current environment.
86+ """
87+ access_key = os.getenv('EC2_ACCESS_KEY')
88+ secret_key = os.getenv('EC2_SECRET_KEY')
89+ clc_url = os.getenv('EC2_URL')
90+
91+ if not access_key or not secret_key or not clc_url:
92+ raise Exception('Missing EC2 environment variables. Please source '
93+ 'the appropriate novarc file before running this '
94+ 'test.')
95+
96+ parts = self.split_clc_url(clc_url)
97+ return boto.connect_ec2(aws_access_key_id=access_key,
98+ aws_secret_access_key=secret_key,
99+ is_secure=parts['is_secure'],
100+ region=RegionInfo(None,
101+ 'nova',
102+ parts['ip']),
103+ port=parts['port'],
104+ path='/services/Cloud',
105+ **kwargs)
106+
107+ def split_clc_url(self, clc_url):
108+ """
109+ Splits a cloud controller endpoint url.
110+ """
111+ parts = httplib.urlsplit(clc_url)
112+ is_secure = parts.scheme == 'https'
113+ ip, port = parts.netloc.split(':')
114+ return {'ip': ip, 'port': int(port), 'is_secure': is_secure}
115+
116+ def create_key_pair(self, conn, key_name):
117+ try:
118+ os.remove('/tmp/%s.pem' % key_name)
119+ except:
120+ pass
121+ key = conn.create_key_pair(key_name)
122+ key.save('/tmp/')
123+ return key
124+
125+ def delete_key_pair(self, conn, key_name):
126+ conn.delete_key_pair(key_name)
127+ try:
128+ os.remove('/tmp/%s.pem' % key_name)
129+ except:
130+ pass
131+
132+ def bundle_image(self, image, kernel=False):
133+ cmd = 'euca-bundle-image -i %s' % image
134+ if kernel:
135+ cmd += ' --kernel true'
136+ status, output = commands.getstatusoutput(cmd)
137+ if status != 0:
138+ print '%s -> \n %s' % (cmd, output)
139+ raise Exception(output)
140+ return True
141+
142+ def upload_image(self, bucket_name, image):
143+ cmd = 'euca-upload-bundle -b %s -m /tmp/%s.manifest.xml' % (bucket_name, image)
144+ status, output = commands.getstatusoutput(cmd)
145+ if status != 0:
146+ print '%s -> \n %s' % (cmd, output)
147+ raise Exception(output)
148+ return True
149+
150+ def delete_bundle_bucket(self, bucket_name):
151+ cmd = 'euca-delete-bundle --clear -b %s' % (bucket_name)
152+ status, output = commands.getstatusoutput(cmd)
153+ if status != 0:
154+ print '%s -> \n%s' % (cmd, output)
155+ raise Exception(output)
156+ return True
157+
158+ def load_config(self):
159+ conf = open(options.config_file, "r")
160+ config = yaml.load(conf)
161+ return config
162
163=== added file 'openstack/uectesting/testing.py'
164--- openstack/uectesting/testing.py 1970-01-01 00:00:00 +0000
165+++ openstack/uectesting/testing.py 2011-01-13 00:51:02 +0000
166@@ -0,0 +1,312 @@
167+import commands
168+import os
169+import random
170+import socket
171+import sys
172+import time
173+import unittest
174+
175+from uectesting import base
176+
177+TEST_PREFIX = 'test%s' % int (random.random()*1000000)
178+TEST_BUCKET = '%s_bucket' % TEST_PREFIX
179+TEST_KEY = '%s_key' % TEST_PREFIX
180+TEST_DATA = {}
181+
182+class UECTestingCase(base.UECTestCase):
183+ def setUp(self):
184+ self.config = self.load_config()
185+ self.conn = self.get_connection()
186+
187+ self.image = self.config['conf']['image']
188+ self.image_name = self.config['conf']['image_name']
189+
190+ self.kernel_image = self.config['conf']['kernel_image']
191+ self.kernel_name = self.config['conf']['kernel_name']
192+
193+ self.ramdisk_image = self.config['conf']['ramdisk_image']
194+ self.ramdisk_name = self.config['conf']['ramdisk_name']
195+
196+ self.bucket_name = self.config['conf']['bucket']
197+
198+ global TEST_DATA
199+ self.data = TEST_DATA
200+
201+class UECImageTest(UECTestingCase):
202+ def setUp(self):
203+ global TEST_DATA
204+ self.data = TEST_DATA
205+
206+ def test_001_can_bundle_image(self):
207+ self.assertTrue(self.bundle_image(self.image))
208+
209+ def test_002_can_upload_image(self):
210+ self.assertTrue(self.upload_image(TEST_BUCKET, self.image_name))
211+
212+ def test_003_can_register_image(self):
213+ image_id = self.conn.register_image('%s/%s.manifest.xml' %
214+ (TEST_BUCKET, self.image_name))
215+ self.assert_(image_id is not None)
216+ self.data['image_id'] = image_id
217+
218+ def test_004_can_bundle_kernel(self):
219+ self.assertTrue(self.bundle_image(self.kernel_image, kernel=True))
220+
221+ def test_005_can_upload_kernel(self):
222+ self.assertTrue(self.upload_image(TEST_BUCKET, self.kernel_name))
223+
224+ def test_006_can_register_kernel(self):
225+ kernel_id = self.conn.register_image('%s/%s.manifest.xml' %
226+ (TEST_BUCKET, self.kernel_name))
227+ self.assert_(kernel_id is not None)
228+ self.data['kernel_id'] = kernel_id
229+
230+ def test_007_images_are_available_within_10_seconds(self):
231+ for i in xrange(10):
232+ image = self.conn.get_image(self.data['image_id'])
233+ if image and image.state == 'available':
234+ break
235+ time.sleep(1)
236+ else:
237+ print image.state
238+ self.assert_(False) # wasn't available within 10 seconds
239+ self.assert_(image.type == 'machine')
240+
241+ for i in xrange(10):
242+ kernel = self.conn.get_image(self.data['kernel_id'])
243+ if kernel and kernel.state == 'available':
244+ break
245+ time.sleep(1)
246+ else:
247+ self.assert_(False) # wasn't available within 10 seconds
248+ self.assert_(kernel.type == 'kernel')
249+
250+ def test_008_can_describe_image_attribute(self):
251+ attrs = self.conn.get_image_attribute(self.data['image_id'],
252+ 'launchPermission')
253+ self.assert_(attrs.name, 'launch_permission')
254+
255+ def test_009_can_modify_image_launch_permission(self):
256+ self.conn.modify_image_attribute(image_id=self.data['image_id'],
257+ operation='add',
258+ attribute='launchPermission',
259+ groups='all')
260+ image = self.conn.get_image(self.data['image_id'])
261+ self.assertEqual(image.id, self.data['image_id'])
262+
263+ def test_010_can_see_launch_permission(self):
264+ attrs = self.conn.get_image_attribute(self.data['image_id'],
265+ 'launchPermission')
266+ self.assert_(attrs.name, 'launch_permission')
267+ self.assert_(attrs.attrs['groups'][0], 'all')
268+
269+ def test_011_user_can_deregister_kernel(self):
270+ self.assertTrue(self.conn.deregister_image(self.data['kernel_id']))
271+
272+ def test_012_can_deregister_image(self):
273+ self.assertTrue(self.conn.deregister_image(self.data['image_id']))
274+
275+ def test_013_can_delete_bundle(self):
276+ self.assertTrue(self.delete_bundle_bucket(TEST_BUCKET))
277+
278+class UECInstanceTest(UECTestingCase):
279+ def setUp(self):
280+ global TEST_DATA
281+ self.data = TEST_DATA
282+
283+ def test_001_can_create_keypair(self):
284+ key = self.create_key_pair(self.conn, TEST_KEY)
285+ self.assertEqual(key.name, TEST_KEY)
286+
287+ def test_002_can_create_instance_with_keypair(self):
288+ reservation = self.conn.run_instances(self.image_name,
289+ key_name=TEST_KEY,
290+ instance_type='m1.tiny')
291+ self.assertEqual(len(reservation.instances), 1)
292+ self.data['instance_id'] = reservation.instances[0].id
293+
294+ def test_003_instance_runs_within_60_seconds(self):
295+ reservations = self.conn.get_all_instances([data['instance_id']])
296+ instance = reservations[0].instances[0]
297+ # allow 60 seconds to exit pending with IP
298+ for x in xrange(60):
299+ instance.update()
300+ if instance.state == u'running':
301+ break
302+ time.sleep(1)
303+ else:
304+ self.fail('instance failed to start')
305+ ip = reservations[0].instances[0].private_dns_name
306+ self.failIf(ip == '0.0.0.0')
307+ self.data['private_ip'] = ip
308+ print self.data['private_ip']
309+
310+ def test_004_can_ping_private_ip(self):
311+ for x in xrange(120):
312+ # ping waits for 1 second
313+ status, output = commands.getstatusoutput(
314+ 'ping -c1 %s' % self.data['private_ip'])
315+ if status == 0:
316+ break
317+ else:
318+ self.fail('could not ping instance')
319+
320+ def test_005_can_ssh_to_private_ip(self):
321+ for x in xrange(30):
322+ try:
323+ conn = self.connect_ssh(self.data['private_ip'], TEST_KEY)
324+ conn.close()
325+ except Exception:
326+ time.sleep(1)
327+ else:
328+ break
329+ else:
330+ self.fail('could not ssh to instance')
331+
332+ def test_006_can_allocate_elastic_ip(self):
333+ result = self.conn.allocate_address()
334+ self.assertTrue(hasattr(result, 'public_ip'))
335+ self.data['public_ip'] = result.public_ip
336+
337+ def test_007_can_associate_ip_with_instance(self):
338+ result = self.conn.associate_address(self.data['instance_id'],
339+ self.data['public_ip'])
340+ self.assertTrue(result)
341+
342+ def test_008_can_ssh_with_public_ip(self):
343+ for x in xrange(30):
344+ try:
345+ conn = self.connect_ssh(self.data['public_ip'], TEST_KEY)
346+ conn.close()
347+ except socket.error:
348+ time.sleep(1)
349+ else:
350+ break
351+ else:
352+ self.fail('could not ssh to instance')
353+
354+ def test_009_can_disassociate_ip_from_instance(self):
355+ result = self.conn.disassociate_address(self.data['public_ip'])
356+ self.assertTrue(result)
357+
358+ def test_010_can_deallocate_elastic_ip(self):
359+ result = self.conn.release_address(self.data['public_ip'])
360+ self.assertTrue(result)
361+
362+ def test_999_tearDown(self):
363+ self.delete_key_pair(self.conn, TEST_KEY)
364+ if self.data.has_key('instance_id'):
365+ self.conn.terminate_instances([data['instance_id']])
366+
367+
368+class UECVolumeTest(UECTestingCase):
369+ def setUp(self):
370+ super(UECVolumeTest, self).setUp()
371+ self.device = '/dev/vdb'
372+
373+ global TEST_DATA
374+ self.data = TEST_DATA
375+
376+ def test_000_setUp(self):
377+ self.create_key_pair(self.conn, TEST_KEY)
378+ reservation = self.conn.run_instances(self.image_name,
379+ instance_type='m1.tiny',
380+ key_name=TEST_KEY)
381+ instance = reservation.instances[0]
382+ self.data['instance'] = instance
383+ for x in xrange(120):
384+ if self.can_ping(instance.private_dns_name):
385+ break
386+ else:
387+ self.fail('unable to start instance')
388+
389+ def test_001_can_create_volume(self):
390+ volume = self.conn.create_volume(1, 'nova')
391+ self.assertEqual(volume.size, 1)
392+ self.data['volume'] = volume
393+ # Give network time to find volume.
394+ time.sleep(5)
395+
396+ def test_002_can_attach_volume(self):
397+ volume = self.data['volume']
398+
399+ for x in xrange(10):
400+ if volume.status == u'available':
401+ break
402+ time.sleep(5)
403+ volume.update()
404+ else:
405+ self.fail('cannot attach volume with state %s' % volume.status)
406+
407+ volume.attach(self.data['instance'].id, self.device)
408+
409+ # Volumes seems to report "available" too soon.
410+ for x in xrange(10):
411+ if volume.status == u'in-use':
412+ break
413+ time.sleep(5)
414+ volume.update()
415+
416+ self.assertEqual(volume.status, u'in-use')
417+
418+ # Give instance time to recognize volume.
419+ time.sleep(5)
420+
421+ def test_003_can_mount_volume(self):
422+ ip = self.data['instance'].private_dns_name
423+ conn = self.connect_ssh(ip, TEST_KEY)
424+ commands = []
425+ commands.append('mkdir -p /mnt/vol')
426+ commands.append('mkfs.ext2 %s' % self.device)
427+ commands.append('mount %s /mnt/vol' % self.device)
428+ commands.append('echo success')
429+ stdin, stdout, stderr = conn.exec_command(' && '.join(commands))
430+ out = stdout.read()
431+ conn.close()
432+ if not out.strip().endswith('success'):
433+ self.fail('Unable to mount: %s %s' % (out, stderr.read()))
434+
435+ def test_004_can_write_to_volume(self):
436+ ip = self.data['instance'].private_dns_name
437+ conn = self.connect_ssh(ip, TEST_KEY)
438+ # FIXME(devcamcar): This doesn't fail if the volume hasn't been mounted
439+ stdin, stdout, stderr = conn.exec_command(
440+ 'echo hello > /mnt/vol/test.txt')
441+ err = stderr.read()
442+ conn.close()
443+ if len(err) > 0:
444+ self.fail('Unable to write to mount: %s' % (err))
445+
446+ def test_005_volume_is_correct_size(self):
447+ ip = self.data['instance'].private_dns_name
448+ conn = self.connect_ssh(ip, TEST_KEY)
449+ stdin, stdout, stderr = conn.exec_command(
450+ "df -h | grep %s | awk {'print $2'}" % self.device)
451+ out = stdout.read()
452+ conn.close()
453+ if not out.strip() == '1008M':
454+ self.fail('Volume is not the right size: %s %s' %
455+ (out, stderr.read()))
456+
457+ def test_006_me_can_umount_volume(self):
458+ ip = self.data['instance'].private_dns_name
459+ conn = self.connect_ssh(ip, TEST_KEY)
460+ stdin, stdout, stderr = conn.exec_command('umount /mnt/vol')
461+ err = stderr.read()
462+ conn.close()
463+ if len(err) > 0:
464+ self.fail('Unable to unmount: %s' % (err))
465+
466+ def test_007_me_can_detach_volume(self):
467+ result = self.conn.detach_volume(volume_id=self.data['volume'].id)
468+ self.assertTrue(result)
469+ time.sleep(5)
470+
471+ def test_008_me_can_delete_volume(self):
472+ result = self.conn.delete_volume(self.data['volume'].id)
473+ self.assertTrue(result)
474+
475+ def test_999_tearDown(self):
476+ self.conn.terminate_instances([self.data['instance'].id])
477+ self.conn.delete_key_pair(TEST_KEY)
478+
479
480=== added file 'openstack/uectesting/utils.py'
481--- openstack/uectesting/utils.py 1970-01-01 00:00:00 +0000
482+++ openstack/uectesting/utils.py 2011-01-13 00:51:02 +0000
483@@ -0,0 +1,6 @@
484+import optparse
485+
486+
487+optparser = optparse.OptionParser()
488+optparser.add_option('-c', dest='config_file', help='Config file to use')
489+(options, args) = optparser.parse_args()
490
491=== added directory 'uec'
492=== renamed file 'README' => 'uec/README'
493=== renamed file 'apt-upgrade.sh' => 'uec/apt-upgrade.sh'
494=== renamed file 'config_multi.yaml' => 'uec/config_multi.yaml'
495=== renamed file 'config_single.yaml' => 'uec/config_single.yaml'
496=== renamed file 'get-logs-ebs.sh' => 'uec/get-logs-ebs.sh'
497=== renamed file 'get-logs.sh' => 'uec/get-logs.sh'
498=== renamed file 'helper.sh' => 'uec/helper.sh'
499=== renamed directory 'images' => 'uec/images'
500=== renamed file 'myutils.py' => 'uec/myutils.py'
501=== renamed file 'reboot.sh' => 'uec/reboot.sh'
502=== renamed directory 'results' => 'uec/results'
503=== renamed file 'scp-uec.sh' => 'uec/scp-uec.sh'
504=== renamed file 'set-ssh.sh' => 'uec/set-ssh.sh'
505=== renamed file 'uec_ebs.py' => 'uec/uec_ebs.py'
506=== renamed file 'uec_instances.py' => 'uec/uec_instances.py'
507=== renamed file 'uec_test.py' => 'uec/uec_test.py'
508=== renamed file 'uec_utils.py' => 'uec/uec_utils.py'
509=== renamed directory 'users' => 'uec/users'
510=== renamed file 'vol-max-alloc.sh' => 'uec/vol-max-alloc.sh'

Subscribers

People subscribed via source and target branches

to all changes: