XenAPI: Unit tests must mock os_xenapi calls

To prevent internal changes in os_xenapi from breaking nova unit
tests, we must mock os_xenapi calls (particular around session
management) rather than attempting to mock the internals of os_xenapi.
This issue was introduced when os_xenapi was split out from nova,
but the UT were not similarly abstracted

Change-Id: Ifdcddb63f64d5759640a62e8ddd3c276fa4fc743
This commit is contained in:
Bob Ball 2017-08-31 13:14:52 +01:00 committed by Jianghua Wang
parent a879286ef8
commit 3cd2a5165e
3 changed files with 29 additions and 8 deletions

View File

@ -13,7 +13,9 @@
# License for the specific language governing permissions and limitations
# under the License.
import base64
import uuid
import zlib
try:
import xmlrpclib
@ -23,7 +25,6 @@ except ImportError:
from eventlet import greenthread
import mock
from os_xenapi.client import host_xenstore
from os_xenapi.client import session as xenapi_session
import six
from nova.compute import power_state
@ -56,7 +57,7 @@ class VMOpsTestBase(stubs.XenAPITestBaseNoDB):
def _setup_mock_vmops(self, product_brand=None, product_version=None):
stubs.stubout_session(self.stubs, xenapi_fake.SessionBase)
self._session = xenapi_session.XenAPISession(
self._session = xenapi_fake.SessionBase(
'http://localhost', 'root', 'test_pass')
self.vmops = vmops.VMOps(self._session, fake.FakeVirtAPI())
@ -235,8 +236,15 @@ class InjectAutoDiskConfigTestCase(VMOpsTestBase):
class GetConsoleOutputTestCase(VMOpsTestBase):
def test_get_console_output_works(self):
def _mock_console_log(self, session, domid):
if domid == 0:
raise session.XenAPI.Failure('No console')
return base64.b64encode(zlib.compress(six.b('dom_id: %s' % domid)))
@mock.patch.object(vmops.vm_management, 'get_console_log')
def test_get_console_output_works(self, mock_console_log):
ctxt = context.RequestContext('user', 'project')
mock_console_log.side_effect = self._mock_console_log
instance = fake_instance.fake_instance_obj(ctxt)
with mock.patch.object(self.vmops, '_get_last_dom_id',
return_value=42) as mock_last_dom:
@ -244,7 +252,9 @@ class GetConsoleOutputTestCase(VMOpsTestBase):
self.vmops.get_console_output(instance))
mock_last_dom.assert_called_once_with(instance, check_rescue=True)
def test_get_console_output_not_available(self):
@mock.patch.object(vmops.vm_management, 'get_console_log')
def test_get_console_output_not_available(self, mock_console_log):
mock_console_log.side_effect = self._mock_console_log
ctxt = context.RequestContext('user', 'project')
instance = fake_instance.fake_instance_obj(ctxt)
# dom_id=0 used to trigger exception in fake XenAPI

View File

@ -25,7 +25,6 @@ import re
import mock
from mox3 import mox
from os_xenapi.client import host_management
from os_xenapi.client import session as xenapi_session
from os_xenapi.client import XenAPI
from oslo_concurrency import lockutils
from oslo_config import fixture as config_fixture
@ -143,8 +142,7 @@ IMAGE_FIXTURES = {
def get_session():
return xenapi_session.XenAPISession(
'http://localhost', 'root', 'test_pass')
return xenapi_fake.SessionBase('http://localhost', 'root', 'test_pass')
def set_image_fixtures():

View File

@ -360,6 +360,7 @@ def _create_local_pif(host_ref):
def _create_object(table, obj):
ref = uuidutils.generate_uuid()
obj['uuid'] = uuidutils.generate_uuid()
obj['ref'] = ref
_db_content[table][ref] = obj
return ref
@ -503,9 +504,11 @@ class Failure(Exception):
class SessionBase(object):
"""Base class for Fake Sessions."""
def __init__(self, uri):
def __init__(self, uri, user=None, passwd=None):
self._session = None
xenapi_session.apply_session_helpers(self)
if user is not None:
self.xenapi.login_with_password(user, passwd)
def pool_get_default_SR(self, _1, pool_ref):
return list(_db_content['pool'].values())[0]['default-SR']
@ -897,11 +900,21 @@ class SessionBase(object):
methodname)
return meth(*full_params)
def call_xenapi(self, *args):
return self.xenapi_request(args[0], args[1:])
def get_all_refs_and_recs(self, cls):
return get_all_records(cls).items()
def get_rec(self, cls, ref):
return _db_content[cls].get(ref, None)
def _login(self, method, params):
self._session = uuidutils.generate_uuid()
_session_info = {'uuid': uuidutils.generate_uuid(),
'this_host': list(_db_content['host'])[0]}
_db_content['session'][self._session] = _session_info
self.host_ref = list(_db_content['host'])[0]
def _logout(self):
s = self._session