From e30801445f8b543d78494ca63be60f85b94d3a53 Mon Sep 17 00:00:00 2001 From: Armando Migliaccio Date: Mon, 13 Dec 2010 20:31:33 +0000 Subject: moving xenapi unittests changes into another branch --- nova/tests/virt_unittest.py | 76 -------------------------- nova/virt/xenapi/fake.py | 128 -------------------------------------------- 2 files changed, 204 deletions(-) delete mode 100644 nova/virt/xenapi/fake.py diff --git a/nova/tests/virt_unittest.py b/nova/tests/virt_unittest.py index 1095662c3..d49383fb7 100644 --- a/nova/tests/virt_unittest.py +++ b/nova/tests/virt_unittest.py @@ -25,14 +25,9 @@ from nova import utils from nova.api.ec2 import cloud from nova.auth import manager from nova.virt import libvirt_conn -from nova.virt.xenapi import fake -from nova.virt.xenapi import volume_utils FLAGS = flags.FLAGS flags.DECLARE('instances_path', 'nova.compute.manager') -# Those are XenAPI related -flags.DECLARE('target_host', 'nova.virt.xenapi_conn') -FLAGS.target_host = '127.0.0.1' class LibvirtConnTestCase(test.TrialTestCase): @@ -262,74 +257,3 @@ class NWFilterTestCase(test.TrialTestCase): d.addCallback(lambda _: self.teardown_security_group()) return d - - -class XenAPIVolumeTestCase(test.TrialTestCase): - - def setUp(self): - super(XenAPIVolumeTestCase, self).setUp() - self.flags(xenapi_use_fake_session=True) - self.session = fake.FakeXenAPISession() - self.helper = volume_utils.VolumeHelper - self.helper.late_import() - - def _create_volume(self, size='0'): - """Create a volume object.""" - vol = {} - vol['size'] = size - vol['user_id'] = 'fake' - vol['project_id'] = 'fake' - vol['host'] = 'localhost' - vol['availability_zone'] = FLAGS.storage_availability_zone - vol['status'] = "creating" - vol['attach_status'] = "detached" - return db.volume_create(context.get_admin_context(), vol) - - def test_create_iscsi_storage_raise_no_exception(self): - vol = self._create_volume() - info = yield self.helper.parse_volume_info(vol['ec2_id'], '/dev/sdc') - label = None # For testing new SRs - description = 'Test-SR' - self.session.fail_next_call = False - sr_ref = self.helper.create_iscsi_storage_blocking(self.session, - info, - label, - description) - self.assertEqual(sr_ref, self.session.SR.FAKE_REF) - db.volume_destroy(context.get_admin_context(), vol['id']) - - def test_create_iscsi_storage_raise_unable_to_create_sr_exception(self): - vol = self._create_volume() - info = yield self.helper.parse_volume_info(vol['ec2_id'], '/dev/sdc') - label = None # For testing new SRs - description = None - self.session.fail_next_call = True - self.assertRaises(volume_utils.StorageError, - self.helper.create_iscsi_storage_blocking, - self.session, - info, - label, - description) - - def test_find_sr_from_vbd_raise_no_exception(self): - sr_ref = yield self.helper.find_sr_from_vbd(self.session, - self.session.VBD.FAKE_REF) - self.assertEqual(sr_ref, self.session.SR.FAKE_REF) - - def test_destroy_iscsi_storage(self): - sr_ref = self.session.SR.FAKE_REF - self.helper.destroy_iscsi_storage_blocking(self.session, sr_ref) - - def test_introduce_vdi_raise_no_exception(self): - sr_ref = self.session.SR.FAKE_REF - self.helper.introduce_vdi_blocking(self.session, sr_ref) - - def test_introduce_vdi_raise_unable_get_vdi_record_exception(self): - sr_ref = self.session.SR.FAKE_REF - self.session.fail_next_call = True - self.assertRaises(volume_utils.StorageError, - self.helper.introduce_vdi_blocking, - self.session, sr_ref) - - def tearDown(self): - super(XenAPIVolumeTestCase, self).tearDown() diff --git a/nova/virt/xenapi/fake.py b/nova/virt/xenapi/fake.py deleted file mode 100644 index 2fed28609..000000000 --- a/nova/virt/xenapi/fake.py +++ /dev/null @@ -1,128 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright (c) 2010 Citrix Systems, 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. - -""" -A fake XenAPI SDK. - -Allows for xenapi helper classes testing. -""" - - -class Failure(Exception): - def __init__(self, message=None): - super(Failure, self).__init__(message) - self.details = [] - - def __str__(self): - return 'Fake XenAPI Exception' - - -class FakeXenAPISession(object): - """ The session to invoke XenAPI SDK calls """ - def __init__(self): - self.fail_next_call = False - - def get_xenapi(self): - """ Return the xenapi object """ - return self - - def get_xenapi_host(self): - """ Return the xenapi host """ - return 'FAKE_XENAPI_HOST' - - def call_xenapi(self, method, *args): - """Call the specified XenAPI method on a background thread. Returns - a Deferred for the result.""" - raise NotImplementedError() - - def async_call_plugin(self, plugin, fn, args): - """Call Async.host.call_plugin on a background thread. Returns a - Deferred with the task reference.""" - raise NotImplementedError() - - def wait_for_task(self, task): - """Return a Deferred that will give the result of the given task. - The task is polled until it completes.""" - raise NotImplementedError() - - def __getattr__(self, name): - return FakeXenAPIObject(name, self) - - -class FakeXenAPIObject(object): - def __init__(self, name, session): - self.name = name - self.session = session - self.FAKE_REF = 'FAKE_REFERENCE_%s' % name - - def get_by_name_label(self, label): - if label is None: - return '' # 'No object found' - else: - return 'FAKE_OBJECT_%s_%s' % (self.name, label) - - def getter(self, *args): - self._check_fail() - return self.FAKE_REF - - def ref_list(self, *args): - self._check_fail() - return [FakeXenAPIRecord()] - - def __getattr__(self, name): - if name == 'create': - return self._create - elif name == 'get_record': - return self._record - elif name == 'introduce' or\ - name == 'forget' or\ - name == 'unplug': - return self._fake_action - elif name.startswith('get_'): - getter = 'get_%s' % self.name - if name == getter: - return self.getter - else: - child = name[name.find('_') + 1:] - if child.endswith('s'): - return FakeXenAPIObject(child[:-1], self.session).ref_list - else: - return FakeXenAPIObject(child, self.session).getter - - def _create(self, *args): - self._check_fail() - return self.FAKE_REF - - def _record(self, *args): - self._check_fail() - return FakeXenAPIRecord() - - def _fake_action(self, *args): - self._check_fail() - pass - - def _check_fail(self): - if self.session.fail_next_call: - self.session.fail_next_call = False # Reset! - raise Failure('Unable to create %s' % self.name) - - -class FakeXenAPIRecord(dict): - def __init__(self): - pass - - def __getitem__(self, attr): - return '' -- cgit From 6e37cf42d758b5040442d9c296b21955d10a7327 Mon Sep 17 00:00:00 2001 From: Armando Migliaccio Date: Tue, 14 Dec 2010 11:48:29 +0000 Subject: final cleanup, after moving unittest work into another branch --- nova/virt/xenapi/__init__.py | 30 ++++++++++++++++++ nova/virt/xenapi/fake.py | 66 +++++++++++++++++++++++++++++++++++++++ nova/virt/xenapi/network_utils.py | 3 +- nova/virt/xenapi/vm_utils.py | 19 ++--------- nova/virt/xenapi/vmops.py | 6 ++-- nova/virt/xenapi/volume_utils.py | 20 ++---------- nova/virt/xenapi/volumeops.py | 8 +++-- nova/virt/xenapi_conn.py | 10 ++++-- 8 files changed, 118 insertions(+), 44 deletions(-) create mode 100644 nova/virt/xenapi/fake.py diff --git a/nova/virt/xenapi/__init__.py b/nova/virt/xenapi/__init__.py index d9abe54c5..1a2903b98 100644 --- a/nova/virt/xenapi/__init__.py +++ b/nova/virt/xenapi/__init__.py @@ -18,3 +18,33 @@ :mod:`xenapi` -- Nova support for XenServer and XCP through XenAPI ================================================================== """ + + +def load_sdk(flags): + """ + This method is used for loading the XenAPI SDK (fake or real) + """ + xenapi_module = \ + flags.xenapi_use_fake_session and 'nova.virt.xenapi.fake' or 'XenAPI' + from_list = \ + flags.xenapi_use_fake_session and ['fake'] or [] + + return __import__(xenapi_module, globals(), locals(), from_list, -1) + + +class HelperBase(): + """ + The class that wraps the helper methods together. + """ + XenAPI = None + + def __init__(self): + return + + @classmethod + def late_import(cls, FLAGS): + """ + Load XenAPI module in for helper class + """ + if cls.XenAPI is None: + cls.XenAPI = load_sdk(FLAGS) diff --git a/nova/virt/xenapi/fake.py b/nova/virt/xenapi/fake.py new file mode 100644 index 000000000..8d6a39a87 --- /dev/null +++ b/nova/virt/xenapi/fake.py @@ -0,0 +1,66 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright (c) 2010 Citrix Systems, 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. + +""" +A fake XenAPI SDK. + +Allows for xenapi helper classes testing. +""" + + +class Failure(Exception): + def __init__(self, message=None): + super(Failure, self).__init__(message) + self.details = [] + + def __str__(self): + return 'Fake XenAPI Exception' + + +class FakeSession(object): + """ + The session to invoke XenAPI SDK calls. + FIXME(armando): this is a placeholder + for the xenapi unittests branch. + """ + def __init__(self, url): + pass + + def get_xenapi(self): + """ Return the xenapi object """ + raise NotImplementedError() + + def get_xenapi_host(self): + """ Return the xenapi host """ + raise NotImplementedError() + + def call_xenapi(self, method, *args): + """Call the specified XenAPI method on a background thread. Returns + a Deferred for the result.""" + raise NotImplementedError() + + def async_call_plugin(self, plugin, fn, args): + """Call Async.host.call_plugin on a background thread. Returns a + Deferred with the task reference.""" + raise NotImplementedError() + + def wait_for_task(self, task): + """Return a Deferred that will give the result of the given task. + The task is polled until it completes.""" + raise NotImplementedError() + + def __getattr__(self, name): + raise NotImplementedError() diff --git a/nova/virt/xenapi/network_utils.py b/nova/virt/xenapi/network_utils.py index 8cb4cce3a..cb745cdaf 100644 --- a/nova/virt/xenapi/network_utils.py +++ b/nova/virt/xenapi/network_utils.py @@ -21,9 +21,10 @@ their lookup functions. """ from twisted.internet import defer +from nova.virt.xenapi import HelperBase -class NetworkHelper(): +class NetworkHelper(HelperBase): """ The class that wraps the helper methods together. """ diff --git a/nova/virt/xenapi/vm_utils.py b/nova/virt/xenapi/vm_utils.py index 89831fe5d..2b0691c01 100644 --- a/nova/virt/xenapi/vm_utils.py +++ b/nova/virt/xenapi/vm_utils.py @@ -32,6 +32,7 @@ from nova.auth.manager import AuthManager from nova.compute import instance_types from nova.compute import power_state from nova.virt import images +from nova.virt.xenapi import HelperBase from nova.virt.xenapi.volume_utils import StorageError FLAGS = flags.FLAGS @@ -44,29 +45,13 @@ XENAPI_POWER_STATE = { 'Crashed': power_state.CRASHED} -class VMHelper(): +class VMHelper(HelperBase): """ The class that wraps the helper methods together. """ - - XenAPI = None - def __init__(self): return - @classmethod - def late_import(cls): - """ - Load XenAPI module in for helper class - """ - xenapi_module = \ - FLAGS.xenapi_use_fake_session and 'nova.virt.xenapi.fake' or 'XenAPI' - from_list = \ - FLAGS.xenapi_use_fake_session and ['fake'] or [] - if cls.XenAPI is None: - cls.XenAPI = __import__(xenapi_module, - globals(), locals(), from_list, -1) - @classmethod @defer.inlineCallbacks def create_vm(cls, session, instance, kernel, ramdisk): diff --git a/nova/virt/xenapi/vmops.py b/nova/virt/xenapi/vmops.py index 9a8db0ad4..c79245972 100644 --- a/nova/virt/xenapi/vmops.py +++ b/nova/virt/xenapi/vmops.py @@ -24,9 +24,11 @@ from twisted.internet import defer from nova import db from nova import context +from nova import flags from nova import exception from nova.auth.manager import AuthManager +from nova.virt.xenapi import load_sdk from nova.virt.xenapi.network_utils import NetworkHelper from nova.virt.xenapi.vm_utils import VMHelper @@ -36,10 +38,10 @@ class VMOps(object): Management class for VM-related tasks """ def __init__(self, session): - self.XenAPI = __import__('XenAPI') + self.XenAPI = load_sdk(flags.FLAGS) self._session = session # Load XenAPI module in the helper class - VMHelper.late_import() + VMHelper.late_import(flags.FLAGS) def list_instances(self): """ List VM instances """ diff --git a/nova/virt/xenapi/volume_utils.py b/nova/virt/xenapi/volume_utils.py index 05143ed91..4482e465c 100644 --- a/nova/virt/xenapi/volume_utils.py +++ b/nova/virt/xenapi/volume_utils.py @@ -30,7 +30,7 @@ from nova import context from nova import flags from nova import process from nova import utils - +from nova.virt.xenapi import HelperBase FLAGS = flags.FLAGS @@ -41,29 +41,13 @@ class StorageError(Exception): super(StorageError, self).__init__(message) -class VolumeHelper(): +class VolumeHelper(HelperBase): """ The class that wraps the helper methods together. """ - - XenAPI = None - def __init__(self): return - @classmethod - def late_import(cls): - """ - Load XenAPI module in for helper class - """ - xenapi_module = \ - FLAGS.xenapi_use_fake_session and 'nova.virt.xenapi.fake' or 'XenAPI' - from_list = \ - FLAGS.xenapi_use_fake_session and ['fake'] or [] - if cls.XenAPI is None: - cls.XenAPI = __import__(xenapi_module, - globals(), locals(), from_list, -1) - @classmethod @utils.deferredToThread def create_iscsi_storage(cls, session, info, label, description): diff --git a/nova/virt/xenapi/volumeops.py b/nova/virt/xenapi/volumeops.py index b1afdc811..1b337a6ed 100644 --- a/nova/virt/xenapi/volumeops.py +++ b/nova/virt/xenapi/volumeops.py @@ -21,6 +21,8 @@ import logging from twisted.internet import defer +from nova import flags +from nova.virt.xenapi import load_sdk from nova.virt.xenapi.vm_utils import VMHelper from nova.virt.xenapi.volume_utils import VolumeHelper from nova.virt.xenapi.volume_utils import StorageError @@ -31,11 +33,11 @@ class VolumeOps(object): Management class for Volume-related tasks """ def __init__(self, session): - self.XenAPI = __import__('XenAPI') + self.XenAPI = load_sdk(flags.FLAGS) self._session = session # Load XenAPI module in the helper classes respectively - VolumeHelper.late_import() - VMHelper.late_import() + VolumeHelper.late_import(flags.FLAGS) + VMHelper.late_import(flags.FLAGS) @defer.inlineCallbacks def attach_volume(self, instance_name, device_path, mountpoint): diff --git a/nova/virt/xenapi_conn.py b/nova/virt/xenapi_conn.py index d8d21e24d..649d5dd04 100644 --- a/nova/virt/xenapi_conn.py +++ b/nova/virt/xenapi_conn.py @@ -59,6 +59,7 @@ from twisted.internet import reactor from nova import utils from nova import flags +from nova.virt.xenapi import load_sdk from nova.virt.xenapi.vmops import VMOps from nova.virt.xenapi.volumeops import VolumeOps @@ -91,7 +92,7 @@ flags.DEFINE_string('target_port', '3260', 'iSCSI Target Port, 3260 Default') flags.DEFINE_string('iqn_prefix', - 'iqn.2010-12.org.openstack', + 'iqn.2010-10.org.openstack', 'IQN Prefix') @@ -156,8 +157,11 @@ class XenAPISession(object): def __init__(self, url, user, pw): # This is loaded late so that there's no need to install this # library when not using XenAPI. - self.XenAPI = __import__('XenAPI') - self._session = self.XenAPI.Session(url) + self.XenAPI = load_sdk(FLAGS) + if FLAGS.xenapi_use_fake_session: + self._session = self.XenAPI.FakeSession(url) + else: + self._session = self.XenAPI.Session(url) self._session.login_with_password(user, pw) def get_xenapi(self): -- cgit