Added flags to smoketests. General cleanup

This commit is contained in:
Devin Carlen 2010-06-23 21:19:08 -07:00
parent 487bb6abc3
commit 8572e639ac
5 changed files with 190 additions and 84 deletions

View File

@ -1,6 +0,0 @@
a test suite to run against a deployed cloud
THIS IS NASA CODE!
It will need to be opensourced by the NASA legal process before it is in the open source
release

30
smoketests/__init__.py Normal file
View File

@ -0,0 +1,30 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2010 United States Government as represented by the
# Administrator of the National Aeronautics and Space Administration.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
:mod:`smoketests` -- Nova Integration "Smoke" Tests
=====================================================
.. automodule:: nova.volume
:platform: Unix
.. moduleauthor:: Jesse Andrews <jesse@ansolabs.com>
.. moduleauthor:: Devin Carlen <devin.carlen@gmail.com>
.. moduleauthor:: Vishvananda Ishaya <vishvananda@yahoo.com>
.. moduleauthor:: Joshua McKenty <joshua@cognition.ca>
.. moduleauthor:: Manish Singh <yosh@gimp.org>
.. moduleauthor:: Andy Smith <andy@anarkystic.com>
"""

42
smoketests/flags.py Normal file
View File

@ -0,0 +1,42 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2010 United States Government as represented by the
# Administrator of the National Aeronautics and Space Administration.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
Package-level global flags are defined here, the rest are defined
where they're used.
"""
import socket
from nova import vendor
from gflags import *
# This keeps pylint from barfing on the imports
FLAGS = FLAGS
DEFINE_string = DEFINE_string
DEFINE_integer = DEFINE_integer
DEFINE_bool = DEFINE_bool
# __GLOBAL FLAGS ONLY__
# Define any app-specific flags in their own files, docs at:
# http://code.google.com/p/python-gflags/source/browse/trunk/gflags.py#39
DEFINE_bool('verbose', False, 'show debug output')
DEFINE_string('admin_access_key', 'admin', 'Access key for admin user')
DEFINE_string('admin_secret_key', 'admin', 'Secret key for admin user')
DEFINE_string('clc_ip', '127.0.0.1', 'IP of cloud controller API')
DEFINE_string('vpn_image_id', 'ami-CLOUDPIPE', 'AMI for cloudpipe vpn server')

View File

@ -1,25 +1,33 @@
# COPYRIGHT NASA
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2010 United States Government as represented by the
# Administrator of the National Aeronautics and Space Administration.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import os, unittest, sys
from commands import getstatusoutput
from paramiko import SSHClient, RSAKey, WarningPolicy
import commands
import os
import random
BUCKET_NAME = 'smoketest'
try:
# pulling from environment means euca-bundle and other shell commands
# are runable without futzing with the environment and zip files
access_key = os.environ['EC2_ACCESS_KEY']
secret_key = os.environ['EC2_SECRET_KEY']
endpoint = os.environ['EC2_URL']
host = endpoint.split('/')[2].split(':')[0] # http://HOST:8773/services/Cloud
except:
print 'you need to source admin rc before running smoketests'
sys.exit(2)
import sys
import unittest
from nova.adminclient import NovaAdminClient
admin = NovaAdminClient(access_key=access_key, secret_key=secret_key, clc_ip=host)
from nova.smoketests import flags
from nova import vendor
import paramiko
nova_admin = NovaAdminClient(access_key=flags.admin_access_key, secret_key=flags.admin_secret_key, clc_ip=host)
class NovaTestCase(unittest.TestCase):
def setUp(self):
@ -29,37 +37,37 @@ class NovaTestCase(unittest.TestCase):
pass
def connect_ssh(self, ip, key_name):
# TODO: set a more reasonable connection timeout time
key = RSAKey.from_private_key_file('/tmp/%s.pem' % key_name)
client = SSHClient()
# TODO(devcamcar): set a more reasonable connection timeout time
key = paramiko.RSAKey.from_private_key_file('/tmp/%s.pem' % key_name)
client = paramiko.SSHClient()
client.load_system_host_keys()
client.set_missing_host_key_policy(WarningPolicy())
client.set_missing_host_key_policy(paramiko.WarningPolicy())
client.connect(ip, username='root', pkey=key)
stdin, stdout, stderr = client.exec_command('uptime')
print 'uptime: ', stdout.read()
return client
def can_ping(self, ip):
return getstatusoutput('ping -c 1 %s' % ip)[0] == 0
return commands.getstatusoutput('ping -c 1 %s' % ip)[0] == 0
@property
def admin(self):
return admin.connection_for('admin')
return nova_admin.connection_for('admin')
def connection_for(self, username):
return admin.connection_for(username)
return nova_admin.connection_for(username)
def create_user(self, username):
return admin.create_user(username)
return nova_admin.create_user(username)
def get_user(self, username):
return admin.get_user(username)
return nova_admin.get_user(username)
def delete_user(self, username):
return admin.delete_user(username)
return nova_admin.delete_user(username)
def get_signed_zip(self, username):
return admin.get_zip(username)
return nova_admin.get_zip(username)
def create_key_pair(self, conn, key_name):
try:
@ -81,7 +89,7 @@ class NovaTestCase(unittest.TestCase):
cmd = 'euca-bundle-image -i %s' % image
if kernel:
cmd += ' --kernel true'
status, output = getstatusoutput(cmd)
status, output = commands.getstatusoutput(cmd)
if status != 0:
print '%s -> \n %s' % (cmd, output)
raise Exception(output)
@ -89,7 +97,7 @@ class NovaTestCase(unittest.TestCase):
def upload_image(self, bucket_name, image):
cmd = 'euca-upload-bundle -b %s -m /tmp/%s.manifest.xml' % (bucket_name, image)
status, output = getstatusoutput(cmd)
status, output = commands.getstatusoutput(cmd)
if status != 0:
print '%s -> \n %s' % (cmd, output)
raise Exception(output)
@ -97,14 +105,14 @@ class NovaTestCase(unittest.TestCase):
def delete_bundle_bucket(self, bucket_name):
cmd = 'euca-delete-bundle --clear -b %s' % (bucket_name)
status, output = getstatusoutput(cmd)
status, output = commands.getstatusoutput(cmd)
if status != 0:
print '%s -> \n%s' % (cmd, output)
raise Exception(output)
return True
def register_image(self, bucket_name, manifest):
conn = admin.connection_for('admin')
conn = nova_admin.connection_for('admin')
return conn.register_image("%s/%s.manifest.xml" % (bucket_name, manifest))
def setUp_test_image(self, image, kernel=False):

View File

@ -1,19 +1,43 @@
# COPYRIGHT NASA
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2010 United States Government as represented by the
# Administrator of the National Aeronautics and Space Administration.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import os, re, sys, time, unittest, random
from novatestcase import NovaTestCase
from commands import getstatusoutput
from paramiko import SSHException
from zipfile import ZipFile, ZIP_DEFLATED
import commands
import os
import random
import re
import sys
import time
import unittest
import zipfile
# TODO: Make endpoint configurable
from nova.smoketests import flags
from nova.smoketests.novatestcase import NovaTestCase
DEBUG = True
from nova import vendor
import paramiko
KERNEL_FILENAME = 'openwrt-x86-vmlinuz'
IMAGE_FILENAME = 'openwrt-x86-ext2.image'
FLAGS = flags.FLAGS
flags.DEFINE_string('bundle_kernel', 'openwrt-x86-vmlinuz',
'Local kernel file to use for bundling tests')
flags.DEFINE_string('bundle_image', 'openwrt-x86-ext2.image',
'Local image file to use for bundling tests')
ZIP_FILENAME = '/tmp/nova-x509.zip'
# TODO(devamcar): Use random tempfile
ZIP_FILENAME = '/tmp/euca-me-x509.zip'
data = {}
@ -38,7 +62,7 @@ class UserTests(NovaTestCase):
output.write(buf)
output.close()
zip = ZipFile(ZIP_FILENAME, 'a', ZIP_DEFLATED)
zip = zipfile.ZipFile(ZIP_FILENAME, 'a', zipfile.ZIP_DEFLATED)
bad = zip.testzip()
zip.close()
@ -70,14 +94,14 @@ class ImageTests(NovaTestCase):
data['image_id'] = image_id
def test_004_admin_can_bundle_kernel(self):
self.assertTrue(self.bundle_image(KERNEL_FILENAME, kernel=True))
self.assertTrue(self.bundle_image(flags.bundle_kernel, kernel=True))
def test_005_admin_can_upload_kernel(self):
self.assertTrue(self.upload_image(test_bucket, KERNEL_FILENAME))
self.assertTrue(self.upload_image(test_bucket, flags.bundle_kernel))
def test_006_admin_can_register_kernel(self):
# FIXME: registeration should verify that bucket/manifest exists before returning successfully!
kernel_id = self.register_image(test_bucket, KERNEL_FILENAME)
# FIXME: registration should verify that bucket/manifest exists before returning successfully!
kernel_id = self.register_image(test_bucket, flags.bundle_kernel)
self.assert_(kernel_id is not None)
data['kernel_id'] = kernel_id
@ -101,56 +125,61 @@ class ImageTests(NovaTestCase):
self.assert_(False) # wasn't available within 10 seconds
self.assert_(kernel.type == 'kernel')
def test_008_images_not_public_by_default(self):
def test_008_admin_can_describe_image_attribute(self):
attrs = self.admin.get_image_attribute(data['image_id'], 'launchPermission')
self.assert_(attrs.name, 'launch_permission')
def test_009_me_cannot_see_non_public_images(self):
conn = self.connection_for(test_username)
images = conn.get_all_images(image_ids=[data['image_id']])
self.assertEqual(len(images), 0)
images = conn.get_all_images(image_ids=[data['kernel_id']])
self.assertEqual(len(images), 0)
def test_009_images_can_be_made_public(self):
userconn = self.connection_for(test_username)
def test_010_admin_can_modify_image_launch_permission(self):
conn = self.connection_for(test_username)
self.admin.modify_image_attribute(image_id=data['image_id'],
operation='add',
attribute='launchPermission',
groups='all')
image = userconn.get_image(data['image_id'])
image = conn.get_image(data['image_id'])
self.assertEqual(image.id, data['image_id'])
self.admin.modify_image_attribute(image_id=data['kernel_id'],
operation='add',
attribute='launchPermission',
groups='all')
image = userconn.get_image(data['kernel_id'])
self.assertEqual(image.id, data['kernel_id'])
def test_011_me_can_list_public_images(self):
conn = self.connection_for(test_username)
images = conn.get_all_images(image_ids=[data['image_id']])
self.assertEqual(len(images), 1)
pass
def test_012_me_can_see_launch_permission(self):
attrs = self.admin.get_image_attribute(data['image_id'], 'launchPermission')
self.assert(_attrs.name, 'launch_permission')
self.assert(_attrs.groups[0], 'all')
# FIXME: add tests that user can launch image
# def test_010_user_can_launch_admin_public_image(self):
# def test_013_user_can_launch_admin_public_image(self):
# # TODO: Use openwrt kernel instead of default kernel
# conn = self.connection_for(test_username)
# reservation = conn.run_instances(data['image_id'])
# self.assertEqual(len(reservation.instances), 1)
# data['my_instance_id'] = reservation.instances[0].id
# def test_011_instances_launch_within_30_seconds(self):
# def test_014_instances_launch_within_30_seconds(self):
# pass
# def test_012_user_can_terminate(self):
# def test_015_user_can_terminate(self):
# conn = self.connection_for(test_username)
# terminated = conn.terminate_instances(instance_ids=[data['my_instance_id']])
# self.assertEqual(len(terminated), 1)
def test_013_admin_can_deregister_kernel(self):
def test_016_admin_can_deregister_kernel(self):
self.assertTrue(self.admin.deregister_image(data['kernel_id']))
def test_014_admin_can_deregister_image(self):
def test_017_admin_can_deregister_image(self):
self.assertTrue(self.admin.deregister_image(data['image_id']))
def test_015_admin_can_delete_bundle(self):
def test_018_admin_can_delete_bundle(self):
self.assertTrue(self.delete_bundle_bucket(test_bucket))
def test_999_tearDown(self):
@ -202,13 +231,13 @@ class SecurityTests(NovaTestCase):
def test_005_can_ping_private_ip(self):
for x in xrange(120):
# ping waits for 1 second
status, output = getstatusoutput("ping -c1 -w1 %s" % data['my_private_ip'])
status, output = commands.getstatusoutput("ping -c1 -w1 %s" % data['my_private_ip'])
if status == 0:
break
else:
self.assert_("could not ping instance")
#def test_005_me_cannot_ssh_when_unauthorized(self):
# self.assertRaises(SSHException, self.connect_ssh, data['my_private_ip'], 'mykey')
# self.assertRaises(paramiko.SSHException, self.connect_ssh, data['my_private_ip'], 'mykey')
#def test_006_me_can_authorize_ssh(self):
# conn = self.connection_for(test_username + '_me')
@ -246,7 +275,7 @@ class SecurityTests(NovaTestCase):
try:
conn = self.connect_ssh(data['my_private_ip'], test_key + 'yourkey')
conn.close()
except SSHException:
except paramiko.SSHException:
pass
else:
self.fail("expected SSHException")
@ -274,7 +303,7 @@ class SecurityTests(NovaTestCase):
# build a script to bundle the instance
# build a script to upload the bundle
# status, output = getstatusoutput('cmd')
# status, output = commands.getstatusoutput('cmd')
# if status == 0:
# print 'ok'
# else:
@ -321,10 +350,13 @@ class RebundlingTests(NovaTestCase):
image = conn.get_image(data['my_image_id'])
self.assertEqual(image, None)
# def test_006_me_can_make_image_public(self):
# # TODO: research this
# self.assert_(False)
#
def test_006_me_can_make_image_public(self):
conn = self.connection_for(test_username)
conn.modify_image_attribute(image_id=data['my_image_id'],
operation='add',
attribute='launchPermission',
groups='all')
def test_007_you_can_see_my_public_image(self):
conn = self.connection_for('you')
image = conn.get_image(data['my_image_id'])
@ -401,7 +433,7 @@ class VolumeTests(NovaTestCase):
# wait for instance to show up
for x in xrange(120):
# ping waits for 1 second
status, output = getstatusoutput("ping -c1 -w1 %s" % data['private_ip'])
status, output = commands.getstatusoutput("ping -c1 -w1 %s" % data['private_ip'])
if status == 0:
break
else: