Merge trunk
This commit is contained in:
@@ -14,22 +14,29 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import re
|
||||
import os
|
||||
|
||||
import eventlet
|
||||
import mox
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
|
||||
from xml.etree.ElementTree import fromstring as xml_to_tree
|
||||
from xml.dom.minidom import parseString as xml_to_dom
|
||||
|
||||
from nova import context
|
||||
from nova import db
|
||||
from nova import exception
|
||||
from nova import flags
|
||||
from nova import test
|
||||
from nova import utils
|
||||
from nova.api.ec2 import cloud
|
||||
from nova.auth import manager
|
||||
from nova.compute import manager as compute_manager
|
||||
from nova.compute import power_state
|
||||
from nova.db.sqlalchemy import models
|
||||
from nova.virt import libvirt_conn
|
||||
|
||||
libvirt = None
|
||||
FLAGS = flags.FLAGS
|
||||
flags.DECLARE('instances_path', 'nova.compute.manager')
|
||||
|
||||
@@ -104,11 +111,28 @@ class LibvirtConnTestCase(test.TestCase):
|
||||
libvirt_conn._late_load_cheetah()
|
||||
self.flags(fake_call=True)
|
||||
self.manager = manager.AuthManager()
|
||||
|
||||
try:
|
||||
pjs = self.manager.get_projects()
|
||||
pjs = [p for p in pjs if p.name == 'fake']
|
||||
if 0 != len(pjs):
|
||||
self.manager.delete_project(pjs[0])
|
||||
|
||||
users = self.manager.get_users()
|
||||
users = [u for u in users if u.name == 'fake']
|
||||
if 0 != len(users):
|
||||
self.manager.delete_user(users[0])
|
||||
except Exception, e:
|
||||
pass
|
||||
|
||||
users = self.manager.get_users()
|
||||
self.user = self.manager.create_user('fake', 'fake', 'fake',
|
||||
admin=True)
|
||||
self.project = self.manager.create_project('fake', 'fake', 'fake')
|
||||
self.network = utils.import_object(FLAGS.network_manager)
|
||||
self.context = context.get_admin_context()
|
||||
FLAGS.instances_path = ''
|
||||
self.call_libvirt_dependant_setup = False
|
||||
|
||||
test_ip = '10.11.12.13'
|
||||
test_instance = {'memory_kb': '1024000',
|
||||
@@ -120,6 +144,58 @@ class LibvirtConnTestCase(test.TestCase):
|
||||
'bridge': 'br101',
|
||||
'instance_type': 'm1.small'}
|
||||
|
||||
def lazy_load_library_exists(self):
|
||||
"""check if libvirt is available."""
|
||||
# try to connect libvirt. if fail, skip test.
|
||||
try:
|
||||
import libvirt
|
||||
import libxml2
|
||||
except ImportError:
|
||||
return False
|
||||
global libvirt
|
||||
libvirt = __import__('libvirt')
|
||||
libvirt_conn.libvirt = __import__('libvirt')
|
||||
libvirt_conn.libxml2 = __import__('libxml2')
|
||||
return True
|
||||
|
||||
def create_fake_libvirt_mock(self, **kwargs):
|
||||
"""Defining mocks for LibvirtConnection(libvirt is not used)."""
|
||||
|
||||
# A fake libvirt.virConnect
|
||||
class FakeLibvirtConnection(object):
|
||||
pass
|
||||
|
||||
# A fake libvirt_conn.IptablesFirewallDriver
|
||||
class FakeIptablesFirewallDriver(object):
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
pass
|
||||
|
||||
def setattr(self, key, val):
|
||||
self.__setattr__(key, val)
|
||||
|
||||
# Creating mocks
|
||||
fake = FakeLibvirtConnection()
|
||||
fakeip = FakeIptablesFirewallDriver
|
||||
# Customizing above fake if necessary
|
||||
for key, val in kwargs.items():
|
||||
fake.__setattr__(key, val)
|
||||
|
||||
# Inevitable mocks for libvirt_conn.LibvirtConnection
|
||||
self.mox.StubOutWithMock(libvirt_conn.utils, 'import_class')
|
||||
libvirt_conn.utils.import_class(mox.IgnoreArg()).AndReturn(fakeip)
|
||||
self.mox.StubOutWithMock(libvirt_conn.LibvirtConnection, '_conn')
|
||||
libvirt_conn.LibvirtConnection._conn = fake
|
||||
|
||||
def create_service(self, **kwargs):
|
||||
service_ref = {'host': kwargs.get('host', 'dummy'),
|
||||
'binary': 'nova-compute',
|
||||
'topic': 'compute',
|
||||
'report_count': 0,
|
||||
'availability_zone': 'zone'}
|
||||
|
||||
return db.service_create(context.get_admin_context(), service_ref)
|
||||
|
||||
def test_xml_and_uri_no_ramdisk_no_kernel(self):
|
||||
instance_data = dict(self.test_instance)
|
||||
self._check_xml_and_uri(instance_data,
|
||||
@@ -262,8 +338,8 @@ class LibvirtConnTestCase(test.TestCase):
|
||||
expected_result,
|
||||
'%s failed common check %d' % (xml, i))
|
||||
|
||||
# This test is supposed to make sure we don't override a specifically
|
||||
# set uri
|
||||
# This test is supposed to make sure we don't
|
||||
# override a specifically set uri
|
||||
#
|
||||
# Deliberately not just assigning this string to FLAGS.libvirt_uri and
|
||||
# checking against that later on. This way we make sure the
|
||||
@@ -277,6 +353,150 @@ class LibvirtConnTestCase(test.TestCase):
|
||||
self.assertEquals(uri, testuri)
|
||||
db.instance_destroy(user_context, instance_ref['id'])
|
||||
|
||||
def test_update_available_resource_works_correctly(self):
|
||||
"""Confirm compute_node table is updated successfully."""
|
||||
org_path = FLAGS.instances_path = ''
|
||||
FLAGS.instances_path = '.'
|
||||
|
||||
# Prepare mocks
|
||||
def getVersion():
|
||||
return 12003
|
||||
|
||||
def getType():
|
||||
return 'qemu'
|
||||
|
||||
def listDomainsID():
|
||||
return []
|
||||
|
||||
service_ref = self.create_service(host='dummy')
|
||||
self.create_fake_libvirt_mock(getVersion=getVersion,
|
||||
getType=getType,
|
||||
listDomainsID=listDomainsID)
|
||||
self.mox.StubOutWithMock(libvirt_conn.LibvirtConnection,
|
||||
'get_cpu_info')
|
||||
libvirt_conn.LibvirtConnection.get_cpu_info().AndReturn('cpuinfo')
|
||||
|
||||
# Start test
|
||||
self.mox.ReplayAll()
|
||||
conn = libvirt_conn.LibvirtConnection(False)
|
||||
conn.update_available_resource(self.context, 'dummy')
|
||||
service_ref = db.service_get(self.context, service_ref['id'])
|
||||
compute_node = service_ref['compute_node'][0]
|
||||
|
||||
if sys.platform.upper() == 'LINUX2':
|
||||
self.assertTrue(compute_node['vcpus'] >= 0)
|
||||
self.assertTrue(compute_node['memory_mb'] > 0)
|
||||
self.assertTrue(compute_node['local_gb'] > 0)
|
||||
self.assertTrue(compute_node['vcpus_used'] == 0)
|
||||
self.assertTrue(compute_node['memory_mb_used'] > 0)
|
||||
self.assertTrue(compute_node['local_gb_used'] > 0)
|
||||
self.assertTrue(len(compute_node['hypervisor_type']) > 0)
|
||||
self.assertTrue(compute_node['hypervisor_version'] > 0)
|
||||
else:
|
||||
self.assertTrue(compute_node['vcpus'] >= 0)
|
||||
self.assertTrue(compute_node['memory_mb'] == 0)
|
||||
self.assertTrue(compute_node['local_gb'] > 0)
|
||||
self.assertTrue(compute_node['vcpus_used'] == 0)
|
||||
self.assertTrue(compute_node['memory_mb_used'] == 0)
|
||||
self.assertTrue(compute_node['local_gb_used'] > 0)
|
||||
self.assertTrue(len(compute_node['hypervisor_type']) > 0)
|
||||
self.assertTrue(compute_node['hypervisor_version'] > 0)
|
||||
|
||||
db.service_destroy(self.context, service_ref['id'])
|
||||
FLAGS.instances_path = org_path
|
||||
|
||||
def test_update_resource_info_no_compute_record_found(self):
|
||||
"""Raise exception if no recorde found on services table."""
|
||||
org_path = FLAGS.instances_path = ''
|
||||
FLAGS.instances_path = '.'
|
||||
self.create_fake_libvirt_mock()
|
||||
|
||||
self.mox.ReplayAll()
|
||||
conn = libvirt_conn.LibvirtConnection(False)
|
||||
self.assertRaises(exception.Invalid,
|
||||
conn.update_available_resource,
|
||||
self.context, 'dummy')
|
||||
|
||||
FLAGS.instances_path = org_path
|
||||
|
||||
def test_ensure_filtering_rules_for_instance_timeout(self):
|
||||
"""ensure_filtering_fules_for_instance() finishes with timeout."""
|
||||
# Skip if non-libvirt environment
|
||||
if not self.lazy_load_library_exists():
|
||||
return
|
||||
|
||||
# Preparing mocks
|
||||
def fake_none(self):
|
||||
return
|
||||
|
||||
def fake_raise(self):
|
||||
raise libvirt.libvirtError('ERR')
|
||||
|
||||
self.create_fake_libvirt_mock(nwfilterLookupByName=fake_raise)
|
||||
instance_ref = db.instance_create(self.context, self.test_instance)
|
||||
|
||||
# Start test
|
||||
self.mox.ReplayAll()
|
||||
try:
|
||||
conn = libvirt_conn.LibvirtConnection(False)
|
||||
conn.firewall_driver.setattr('setup_basic_filtering', fake_none)
|
||||
conn.firewall_driver.setattr('prepare_instance_filter', fake_none)
|
||||
conn.ensure_filtering_rules_for_instance(instance_ref)
|
||||
except exception.Error, e:
|
||||
c1 = (0 <= e.message.find('Timeout migrating for'))
|
||||
self.assertTrue(c1)
|
||||
|
||||
db.instance_destroy(self.context, instance_ref['id'])
|
||||
|
||||
def test_live_migration_raises_exception(self):
|
||||
"""Confirms recover method is called when exceptions are raised."""
|
||||
# Skip if non-libvirt environment
|
||||
if not self.lazy_load_library_exists():
|
||||
return
|
||||
|
||||
# Preparing data
|
||||
self.compute = utils.import_object(FLAGS.compute_manager)
|
||||
instance_dict = {'host': 'fake', 'state': power_state.RUNNING,
|
||||
'state_description': 'running'}
|
||||
instance_ref = db.instance_create(self.context, self.test_instance)
|
||||
instance_ref = db.instance_update(self.context, instance_ref['id'],
|
||||
instance_dict)
|
||||
vol_dict = {'status': 'migrating', 'size': 1}
|
||||
volume_ref = db.volume_create(self.context, vol_dict)
|
||||
db.volume_attached(self.context, volume_ref['id'], instance_ref['id'],
|
||||
'/dev/fake')
|
||||
|
||||
# Preparing mocks
|
||||
vdmock = self.mox.CreateMock(libvirt.virDomain)
|
||||
self.mox.StubOutWithMock(vdmock, "migrateToURI")
|
||||
vdmock.migrateToURI(FLAGS.live_migration_uri % 'dest',
|
||||
mox.IgnoreArg(),
|
||||
None, FLAGS.live_migration_bandwidth).\
|
||||
AndRaise(libvirt.libvirtError('ERR'))
|
||||
|
||||
def fake_lookup(instance_name):
|
||||
if instance_name == instance_ref.name:
|
||||
return vdmock
|
||||
|
||||
self.create_fake_libvirt_mock(lookupByName=fake_lookup)
|
||||
|
||||
# Start test
|
||||
self.mox.ReplayAll()
|
||||
conn = libvirt_conn.LibvirtConnection(False)
|
||||
self.assertRaises(libvirt.libvirtError,
|
||||
conn._live_migration,
|
||||
self.context, instance_ref, 'dest', '',
|
||||
self.compute.recover_live_migration)
|
||||
|
||||
instance_ref = db.instance_get(self.context, instance_ref['id'])
|
||||
self.assertTrue(instance_ref['state_description'] == 'running')
|
||||
self.assertTrue(instance_ref['state'] == power_state.RUNNING)
|
||||
volume_ref = db.volume_get(self.context, volume_ref['id'])
|
||||
self.assertTrue(volume_ref['status'] == 'in-use')
|
||||
|
||||
db.volume_destroy(self.context, volume_ref['id'])
|
||||
db.instance_destroy(self.context, instance_ref['id'])
|
||||
|
||||
def tearDown(self):
|
||||
self.manager.delete_project(self.project)
|
||||
self.manager.delete_user(self.user)
|
||||
|
||||
Reference in New Issue
Block a user