Merged with trunk

This commit is contained in:
Anne Gentle
2011-01-07 10:57:53 -06:00
8 changed files with 126 additions and 34 deletions

View File

@@ -30,3 +30,4 @@
<rconradharris@gmail.com> <rick.harris@rackspace.com> <rconradharris@gmail.com> <rick.harris@rackspace.com>
<corywright@gmail.com> <cory.wright@rackspace.com> <corywright@gmail.com> <cory.wright@rackspace.com>
<ant@openstack.org> <amesserl@rackspace.com> <ant@openstack.org> <amesserl@rackspace.com>
<chiradeep@cloud.com> <chiradeep@chiradeep-lt2>

View File

@@ -3,6 +3,7 @@ Anne Gentle <anne@openstack.org>
Anthony Young <sleepsonthefloor@gmail.com> Anthony Young <sleepsonthefloor@gmail.com>
Antony Messerli <ant@openstack.org> Antony Messerli <ant@openstack.org>
Armando Migliaccio <Armando.Migliaccio@eu.citrix.com> Armando Migliaccio <Armando.Migliaccio@eu.citrix.com>
Chiradeep Vittal <chiradeep@cloud.com>
Chris Behrens <cbehrens@codestud.com> Chris Behrens <cbehrens@codestud.com>
Chmouel Boudjnah <chmouel@chmouel.com> Chmouel Boudjnah <chmouel@chmouel.com>
Cory Wright <corywright@gmail.com> Cory Wright <corywright@gmail.com>

View File

@@ -23,12 +23,9 @@ import base64
import boto import boto
import httplib import httplib
from nova import flags
from boto.ec2.regioninfo import RegionInfo from boto.ec2.regioninfo import RegionInfo
FLAGS = flags.FLAGS
DEFAULT_CLC_URL = 'http://127.0.0.1:8773' DEFAULT_CLC_URL = 'http://127.0.0.1:8773'
DEFAULT_REGION = 'nova' DEFAULT_REGION = 'nova'
@@ -199,8 +196,8 @@ class NovaAdminClient(object):
self, self,
clc_url=DEFAULT_CLC_URL, clc_url=DEFAULT_CLC_URL,
region=DEFAULT_REGION, region=DEFAULT_REGION,
access_key=FLAGS.aws_access_key_id, access_key=None,
secret_key=FLAGS.aws_secret_access_key, secret_key=None,
**kwargs): **kwargs):
parts = self.split_clc_url(clc_url) parts = self.split_clc_url(clc_url)

View File

@@ -266,6 +266,8 @@ DEFINE_string('sql_connection',
DEFINE_string('sql_idle_timeout', DEFINE_string('sql_idle_timeout',
'3600', '3600',
'timeout for idle sql database connections') 'timeout for idle sql database connections')
DEFINE_integer('sql_max_retries', 12, 'sql connection attempts')
DEFINE_integer('sql_retry_interval', 10, 'sql connection retry interval')
DEFINE_string('compute_manager', 'nova.compute.manager.ComputeManager', DEFINE_string('compute_manager', 'nova.compute.manager.ComputeManager',
'Manager for compute') 'Manager for compute')

View File

@@ -0,0 +1,71 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
#
# Copyright 2010 Cloud.com, Inc
#
# 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.
"""
Tests For Hyper-V driver
"""
import random
from nova import context
from nova import db
from nova import flags
from nova import test
from nova.auth import manager
from nova.virt import hyperv
FLAGS = flags.FLAGS
FLAGS.connection_type = 'hyperv'
class HyperVTestCase(test.TestCase):
"""Test cases for the Hyper-V driver"""
def setUp(self):
super(HyperVTestCase, self).setUp()
self.manager = manager.AuthManager()
self.user = self.manager.create_user('fake', 'fake', 'fake',
admin=True)
self.project = self.manager.create_project('fake', 'fake', 'fake')
self.context = context.RequestContext(self.user, self.project)
def test_create_destroy(self):
"""Create a VM and destroy it"""
instance = {'internal_id': random.randint(1, 1000000),
'memory_mb': '1024',
'mac_address': '02:12:34:46:56:67',
'vcpus': 2,
'project_id': 'fake',
'instance_type': 'm1.small'}
instance_ref = db.instance_create(self.context, instance)
conn = hyperv.get_connection(False)
conn._create_vm(instance_ref) # pylint: disable-msg=W0212
found = [n for n in conn.list_instances()
if n == instance_ref['name']]
self.assertTrue(len(found) == 1)
info = conn.get_info(instance_ref['name'])
#Unfortunately since the vm is not running at this point,
#we cannot obtain memory information from get_info
self.assertEquals(info['num_cpu'], instance_ref['vcpus'])
conn.destroy(instance_ref)
found = [n for n in conn.list_instances()
if n == instance_ref['name']]
self.assertTrue(len(found) == 0)
def tearDown(self):
super(HyperVTestCase, self).tearDown()
self.manager.delete_project(self.project)
self.manager.delete_user(self.user)

View File

@@ -106,7 +106,7 @@ class CloudTestCase(test.TestCase):
self.cloud.allocate_address(self.context) self.cloud.allocate_address(self.context)
inst = db.instance_create(self.context, {'host': FLAGS.host}) inst = db.instance_create(self.context, {'host': FLAGS.host})
fixed = self.network.allocate_fixed_ip(self.context, inst['id']) fixed = self.network.allocate_fixed_ip(self.context, inst['id'])
ec2_id = cloud.internal_id_to_ec2_id(inst['internal_id']) ec2_id = cloud.id_to_ec2_id(inst['id'])
self.cloud.associate_address(self.context, self.cloud.associate_address(self.context,
instance_id=ec2_id, instance_id=ec2_id,
public_ip=address) public_ip=address)
@@ -127,9 +127,9 @@ class CloudTestCase(test.TestCase):
result = self.cloud.describe_volumes(self.context) result = self.cloud.describe_volumes(self.context)
self.assertEqual(len(result['volumeSet']), 2) self.assertEqual(len(result['volumeSet']), 2)
result = self.cloud.describe_volumes(self.context, result = self.cloud.describe_volumes(self.context,
volume_id=[vol2['ec2_id']]) volume_id=[vol2['id']])
self.assertEqual(len(result['volumeSet']), 1) self.assertEqual(len(result['volumeSet']), 1)
self.assertEqual(result['volumeSet'][0]['volumeId'], vol2['ec2_id']) self.assertEqual(result['volumeSet'][0]['volumeId'], vol2['id'])
db.volume_destroy(self.context, vol1['id']) db.volume_destroy(self.context, vol1['id'])
db.volume_destroy(self.context, vol2['id']) db.volume_destroy(self.context, vol2['id'])
@@ -140,15 +140,16 @@ class CloudTestCase(test.TestCase):
kwargs = {'image_id': image_id, kwargs = {'image_id': image_id,
'instance_type': instance_type, 'instance_type': instance_type,
'max_count': max_count} 'max_count': max_count}
rv = yield self.cloud.run_instances(self.context, **kwargs) rv = self.cloud.run_instances(self.context, **kwargs)
print rv
instance_id = rv['instancesSet'][0]['instanceId'] instance_id = rv['instancesSet'][0]['instanceId']
output = yield self.cloud.get_console_output(context=self.context, output = self.cloud.get_console_output(context=self.context,
instance_id=[instance_id]) instance_id=[instance_id])
self.assertEquals(b64decode(output['output']), 'FAKE CONSOLE OUTPUT') self.assertEquals(b64decode(output['output']), 'FAKE CONSOLE OUTPUT')
# TODO(soren): We need this until we can stop polling in the rpc code # TODO(soren): We need this until we can stop polling in the rpc code
# for unit tests. # for unit tests.
greenthread.sleep(0.3) greenthread.sleep(0.3)
rv = yield self.cloud.terminate_instances(self.context, [instance_id]) rv = self.cloud.terminate_instances(self.context, [instance_id])
def test_key_generation(self): def test_key_generation(self):
result = self._create_key('test') result = self._create_key('test')
@@ -186,7 +187,7 @@ class CloudTestCase(test.TestCase):
kwargs = {'image_id': image_id, kwargs = {'image_id': image_id,
'instance_type': instance_type, 'instance_type': instance_type,
'max_count': max_count} 'max_count': max_count}
rv = yield self.cloud.run_instances(self.context, **kwargs) rv = self.cloud.run_instances(self.context, **kwargs)
# TODO: check for proper response # TODO: check for proper response
instance_id = rv['reservationSet'][0].keys()[0] instance_id = rv['reservationSet'][0].keys()[0]
instance = rv['reservationSet'][0][instance_id][0] instance = rv['reservationSet'][0][instance_id][0]
@@ -209,7 +210,7 @@ class CloudTestCase(test.TestCase):
for instance in reservations[reservations.keys()[0]]: for instance in reservations[reservations.keys()[0]]:
instance_id = instance['instance_id'] instance_id = instance['instance_id']
logging.debug("Terminating instance %s" % instance_id) logging.debug("Terminating instance %s" % instance_id)
rv = yield self.compute.terminate_instance(instance_id) rv = self.compute.terminate_instance(instance_id)
def test_instance_update_state(self): def test_instance_update_state(self):
def instance(num): def instance(num):
@@ -296,7 +297,7 @@ class CloudTestCase(test.TestCase):
def test_update_of_instance_display_fields(self): def test_update_of_instance_display_fields(self):
inst = db.instance_create(self.context, {}) inst = db.instance_create(self.context, {})
ec2_id = cloud.internal_id_to_ec2_id(inst['internal_id']) ec2_id = cloud.id_to_ec2_id(inst['id'])
self.cloud.update_instance(self.context, ec2_id, self.cloud.update_instance(self.context, ec2_id,
display_name='c00l 1m4g3') display_name='c00l 1m4g3')
inst = db.instance_get(self.context, inst['id']) inst = db.instance_get(self.context, inst['id'])

View File

@@ -22,6 +22,7 @@ Tests For Compute
import datetime import datetime
import logging import logging
from nova import compute
from nova import context from nova import context
from nova import db from nova import db
from nova import exception from nova import exception
@@ -29,7 +30,6 @@ from nova import flags
from nova import test from nova import test
from nova import utils from nova import utils
from nova.auth import manager from nova.auth import manager
from nova.compute import api as compute_api
FLAGS = flags.FLAGS FLAGS = flags.FLAGS
@@ -44,7 +44,7 @@ class ComputeTestCase(test.TestCase):
stub_network=True, stub_network=True,
network_manager='nova.network.manager.FlatManager') network_manager='nova.network.manager.FlatManager')
self.compute = utils.import_object(FLAGS.compute_manager) self.compute = utils.import_object(FLAGS.compute_manager)
self.compute_api = compute_api.ComputeAPI() self.compute_api = compute.API()
self.manager = manager.AuthManager() self.manager = manager.AuthManager()
self.user = self.manager.create_user('fake', 'fake', 'fake') self.user = self.manager.create_user('fake', 'fake', 'fake')
self.project = self.manager.create_project('fake', 'fake', 'fake') self.project = self.manager.create_project('fake', 'fake', 'fake')
@@ -72,7 +72,7 @@ class ComputeTestCase(test.TestCase):
"""Verify that an instance cannot be created without a display_name.""" """Verify that an instance cannot be created without a display_name."""
cases = [dict(), dict(display_name=None)] cases = [dict(), dict(display_name=None)]
for instance in cases: for instance in cases:
ref = self.compute_api.create_instances(self.context, ref = self.compute_api.create(self.context,
FLAGS.default_instance_type, None, **instance) FLAGS.default_instance_type, None, **instance)
try: try:
self.assertNotEqual(ref[0].display_name, None) self.assertNotEqual(ref[0].display_name, None)
@@ -80,13 +80,13 @@ class ComputeTestCase(test.TestCase):
db.instance_destroy(self.context, ref[0]['id']) db.instance_destroy(self.context, ref[0]['id'])
def test_create_instance_associates_security_groups(self): def test_create_instance_associates_security_groups(self):
"""Make sure create_instances associates security groups""" """Make sure create associates security groups"""
values = {'name': 'default', values = {'name': 'default',
'description': 'default', 'description': 'default',
'user_id': self.user.id, 'user_id': self.user.id,
'project_id': self.project.id} 'project_id': self.project.id}
group = db.security_group_create(self.context, values) group = db.security_group_create(self.context, values)
ref = self.compute_api.create_instances(self.context, ref = self.compute_api.create(self.context,
FLAGS.default_instance_type, None, security_group=['default']) FLAGS.default_instance_type, None, security_group=['default'])
try: try:
self.assertEqual(len(ref[0]['security_groups']), 1) self.assertEqual(len(ref[0]['security_groups']), 1)
@@ -178,3 +178,22 @@ class ComputeTestCase(test.TestCase):
self.context, self.context,
instance_id) instance_id)
self.compute.terminate_instance(self.context, instance_id) self.compute.terminate_instance(self.context, instance_id)
def test_lock(self):
"""ensure locked instance cannot be changed"""
instance_id = self._create_instance()
self.compute.run_instance(self.context, instance_id)
non_admin_context = context.RequestContext(None, None, False, False)
# decorator should return False (fail) with locked nonadmin context
self.compute.lock_instance(self.context, instance_id)
ret_val = self.compute.reboot_instance(non_admin_context, instance_id)
self.assertEqual(ret_val, False)
# decorator should return None (success) with unlocked nonadmin context
self.compute.unlock_instance(self.context, instance_id)
ret_val = self.compute.reboot_instance(non_admin_context, instance_id)
self.assertEqual(ret_val, None)
self.compute.terminate_instance(self.context, instance_id)

View File

@@ -79,8 +79,8 @@ class XenAPIVolumeTestCase(test.TestCase):
helper = volume_utils.VolumeHelper helper = volume_utils.VolumeHelper
helper.XenAPI = session.get_imported_xenapi() helper.XenAPI = session.get_imported_xenapi()
vol = self._create_volume() vol = self._create_volume()
info = helper.parse_volume_info(vol['ec2_id'], '/dev/sdc') info = helper.parse_volume_info(vol['id'], '/dev/sdc')
label = 'SR-%s' % vol['ec2_id'] label = 'SR-%s' % vol['id']
description = 'Test-SR' description = 'Test-SR'
sr_ref = helper.create_iscsi_storage(session, info, label, description) sr_ref = helper.create_iscsi_storage(session, info, label, description)
srs = xenapi_fake.get_all('SR') srs = xenapi_fake.get_all('SR')
@@ -97,7 +97,7 @@ class XenAPIVolumeTestCase(test.TestCase):
# oops, wrong mount point! # oops, wrong mount point!
self.assertRaises(volume_utils.StorageError, self.assertRaises(volume_utils.StorageError,
helper.parse_volume_info, helper.parse_volume_info,
vol['ec2_id'], vol['id'],
'/dev/sd') '/dev/sd')
db.volume_destroy(context.get_admin_context(), vol['id']) db.volume_destroy(context.get_admin_context(), vol['id'])
@@ -108,8 +108,7 @@ class XenAPIVolumeTestCase(test.TestCase):
volume = self._create_volume() volume = self._create_volume()
instance = db.instance_create(self.values) instance = db.instance_create(self.values)
xenapi_fake.create_vm(instance.name, 'Running') xenapi_fake.create_vm(instance.name, 'Running')
result = conn.attach_volume(instance.name, volume['ec2_id'], result = conn.attach_volume(instance.name, volume['id'], '/dev/sdc')
'/dev/sdc')
def check(): def check():
# check that the VM has a VBD attached to it # check that the VM has a VBD attached to it
@@ -134,7 +133,7 @@ class XenAPIVolumeTestCase(test.TestCase):
self.assertRaises(Exception, self.assertRaises(Exception,
conn.attach_volume, conn.attach_volume,
instance.name, instance.name,
volume['ec2_id'], volume['id'],
'/dev/sdc') '/dev/sdc')
def tearDown(self): def tearDown(self):
@@ -250,15 +249,16 @@ class XenAPIVMTestCase(test.TestCase):
def _create_instance(self): def _create_instance(self):
"""Creates and spawns a test instance""" """Creates and spawns a test instance"""
values = {'name': 1, 'id': 1, values = {
'project_id': self.project.id, 'name': 1,
'user_id': self.user.id, 'id': 1,
'image_id': 1, 'project_id': self.project.id,
'kernel_id': 2, 'user_id': self.user.id,
'ramdisk_id': 3, 'image_id': 1,
'instance_type': 'm1.large', 'kernel_id': 2,
'mac_address': 'aa:bb:cc:dd:ee:ff' 'ramdisk_id': 3,
} 'instance_type': 'm1.large',
'mac_address': 'aa:bb:cc:dd:ee:ff'}
instance = db.instance_create(values) instance = db.instance_create(values)
self.conn.spawn(instance) self.conn.spawn(instance)
return instance return instance