summaryrefslogtreecommitdiff
path: root/nova/tests
diff options
context:
space:
mode:
authorHuan Xie <huan.xie@citrix.com>2017-04-05 00:06:06 -0700
committerHuan Xie <huan.xie@citrix.com>2017-06-06 22:01:24 -0700
commita2f6aac01de30c5b3031b9ef9d0130c77ebc685d (patch)
tree9120171e5faf15e01de4fe6f6174cf760c257350 /nova/tests
parent72119868b27b293d5fa60c19392c0ba08e3df9b3 (diff)
downloadnova-a2f6aac01de30c5b3031b9ef9d0130c77ebc685d.tar.gz
XenAPI: use os-xenapi 0.2.0 in nova
This patch is to change nova project to use os-xenapi 0.2.0 which has added python interfaces for calling dom0 plugins 1. use os_xenapi.client.host_network 2. use os_xenapi.client.disk_management 3. use os_xenapi.client.vm_management 4. use os_xenapi.client.host_xenstore 5. use os_xenapi.client.host_agent 6. use os_xenapi.client.host_management 7. use os_xenapi.client.host_glance Change-Id: Id87b83ef3ca496525f63b9c7b731e8a22c693e02
Diffstat (limited to 'nova/tests')
-rw-r--r--nova/tests/unit/virt/xenapi/image/test_glance.py143
-rw-r--r--nova/tests/unit/virt/xenapi/test_agent.py119
-rw-r--r--nova/tests/unit/virt/xenapi/test_vif.py18
-rw-r--r--nova/tests/unit/virt/xenapi/test_vm_utils.py78
-rw-r--r--nova/tests/unit/virt/xenapi/test_vmops.py43
-rw-r--r--nova/tests/unit/virt/xenapi/test_xenapi.py91
6 files changed, 305 insertions, 187 deletions
diff --git a/nova/tests/unit/virt/xenapi/image/test_glance.py b/nova/tests/unit/virt/xenapi/image/test_glance.py
index 5d43317186..0e4c3da7c1 100644
--- a/nova/tests/unit/virt/xenapi/image/test_glance.py
+++ b/nova/tests/unit/virt/xenapi/image/test_glance.py
@@ -17,12 +17,15 @@ import random
import time
import mock
+from os_xenapi.client import host_glance
from os_xenapi.client import XenAPI
from nova.compute import utils as compute_utils
from nova import context
from nova import exception
+from nova.image import glance as common_glance
from nova.tests.unit.virt.xenapi import stubs
+from nova import utils
from nova.virt.xenapi import driver as xenapi_conn
from nova.virt.xenapi import fake
from nova.virt.xenapi.image import glance
@@ -121,50 +124,114 @@ class TestGlanceStore(stubs.XenAPITestBaseNoDB):
def _get_upload_params(self, auto_disk_config=True,
expected_os_type='default'):
- params = self._get_params()
+ params = {}
params['vdi_uuids'] = ['fake_vdi_uuid']
params['properties'] = {'auto_disk_config': auto_disk_config,
'os_type': expected_os_type}
return params
- def _test_upload_image(self, auto_disk_config, expected_os_type='default'):
- params = self._get_upload_params(auto_disk_config, expected_os_type)
- with mock.patch.object(self.session, 'call_plugin_serialized'
- ) as mock_call_plugin:
- self.store.upload_image(self.context, self.session, self.instance,
- 'fake_image_uuid', ['fake_vdi_uuid'])
-
- mock_call_plugin.assert_called_once_with('glance.py',
- 'upload_vhd2',
- **params)
-
- def test_upload_image(self):
- self._test_upload_image(True)
-
- def test_upload_image_None_os_type(self):
+ @mock.patch.object(utils, 'get_auto_disk_config_from_instance')
+ @mock.patch.object(common_glance, 'generate_identity_headers')
+ @mock.patch.object(vm_utils, 'get_sr_path')
+ @mock.patch.object(host_glance, 'upload_vhd')
+ def test_upload_image(self, mock_upload, mock_sr_path, mock_extra_header,
+ mock_disk_config):
+ params = self._get_upload_params()
+ mock_upload.return_value = 'fake_upload'
+ mock_sr_path.return_value = 'fake_sr_path'
+ mock_extra_header.return_value = 'fake_extra_header'
+ mock_disk_config.return_value = 'true'
+ self.store.upload_image(self.context, self.session, self.instance,
+ 'fake_image_uuid', ['fake_vdi_uuid'])
+
+ mock_sr_path.assert_called_once_with(self.session)
+ mock_extra_header.assert_called_once_with(self.context)
+ mock_upload.assert_called_once_with(
+ self.session, 0, mock.ANY, mock.ANY, 'fake_image_uuid',
+ 'fake_sr_path', 'fake_extra_header', **params)
+
+ @mock.patch.object(utils, 'get_auto_disk_config_from_instance')
+ @mock.patch.object(common_glance, 'generate_identity_headers')
+ @mock.patch.object(vm_utils, 'get_sr_path')
+ @mock.patch.object(host_glance, 'upload_vhd')
+ def test_upload_image_None_os_type(self, mock_upload, mock_sr_path,
+ mock_extra_header, mock_disk_config):
self.instance['os_type'] = None
- self._test_upload_image(True, 'linux')
-
- def test_upload_image_no_os_type(self):
+ mock_sr_path.return_value = 'fake_sr_path'
+ mock_extra_header.return_value = 'fake_extra_header'
+ mock_upload.return_value = 'fake_upload'
+ mock_disk_config.return_value = 'true'
+ params = self._get_upload_params(True, 'linux')
+ self.store.upload_image(self.context, self.session, self.instance,
+ 'fake_image_uuid', ['fake_vdi_uuid'])
+
+ mock_sr_path.assert_called_once_with(self.session)
+ mock_extra_header.assert_called_once_with(self.context)
+ mock_upload.assert_called_once_with(
+ self.session, 0, mock.ANY, mock.ANY, 'fake_image_uuid',
+ 'fake_sr_path', 'fake_extra_header', **params)
+ mock_disk_config.assert_called_once_with(self.instance)
+
+ @mock.patch.object(utils, 'get_auto_disk_config_from_instance')
+ @mock.patch.object(common_glance, 'generate_identity_headers')
+ @mock.patch.object(vm_utils, 'get_sr_path')
+ @mock.patch.object(host_glance, 'upload_vhd')
+ def test_upload_image_no_os_type(self, mock_upload, mock_sr_path,
+ mock_extra_header, mock_disk_config):
+ mock_sr_path.return_value = 'fake_sr_path'
+ mock_extra_header.return_value = 'fake_extra_header'
+ mock_upload.return_value = 'fake_upload'
del self.instance['os_type']
- self._test_upload_image(True, 'linux')
-
- def test_upload_image_auto_config_disk_disabled(self):
+ params = self._get_upload_params(True, 'linux')
+ self.store.upload_image(self.context, self.session, self.instance,
+ 'fake_image_uuid', ['fake_vdi_uuid'])
+
+ mock_sr_path.assert_called_once_with(self.session)
+ mock_extra_header.assert_called_once_with(self.context)
+ mock_upload.assert_called_once_with(
+ self.session, 0, mock.ANY, mock.ANY, 'fake_image_uuid',
+ 'fake_sr_path', 'fake_extra_header', **params)
+ mock_disk_config.assert_called_once_with(self.instance)
+
+ @mock.patch.object(common_glance, 'generate_identity_headers')
+ @mock.patch.object(vm_utils, 'get_sr_path')
+ @mock.patch.object(host_glance, 'upload_vhd')
+ def test_upload_image_auto_config_disk_disabled(
+ self, mock_upload, mock_sr_path, mock_extra_header):
+ mock_sr_path.return_value = 'fake_sr_path'
+ mock_extra_header.return_value = 'fake_extra_header'
+ mock_upload.return_value = 'fake_upload'
sys_meta = [{"key": "image_auto_disk_config", "value": "Disabled"}]
self.instance["system_metadata"] = sys_meta
- self._test_upload_image("disabled")
-
- def test_upload_image_raises_exception(self):
+ params = self._get_upload_params("disabled")
+ self.store.upload_image(self.context, self.session, self.instance,
+ 'fake_image_uuid', ['fake_vdi_uuid'])
+
+ mock_sr_path.assert_called_once_with(self.session)
+ mock_extra_header.assert_called_once_with(self.context)
+ mock_upload.assert_called_once_with(
+ self.session, 0, mock.ANY, mock.ANY, 'fake_image_uuid',
+ 'fake_sr_path', 'fake_extra_header', **params)
+
+ @mock.patch.object(common_glance, 'generate_identity_headers')
+ @mock.patch.object(vm_utils, 'get_sr_path')
+ @mock.patch.object(host_glance, 'upload_vhd')
+ def test_upload_image_raises_exception(self, mock_upload, mock_sr_path,
+ mock_extra_header):
+
+ mock_sr_path.return_value = 'fake_sr_path'
+ mock_extra_header.return_value = 'fake_extra_header'
+ mock_upload.side_effect = RuntimeError
params = self._get_upload_params()
- with mock.patch.object(self.session, 'call_plugin_serialized',
- side_effect=RuntimeError) as mock_call_plugin:
- self.assertRaises(RuntimeError, self.store.upload_image,
- self.context, self.session, self.instance,
- 'fake_image_uuid', ['fake_vdi_uuid'])
+ self.assertRaises(RuntimeError, self.store.upload_image,
+ self.context, self.session, self.instance,
+ 'fake_image_uuid', ['fake_vdi_uuid'])
- mock_call_plugin.assert_called_once_with('glance.py',
- 'upload_vhd2',
- **params)
+ mock_sr_path.assert_called_once_with(self.session)
+ mock_extra_header.assert_called_once_with(self.context)
+ mock_upload.assert_called_once_with(
+ self.session, 0, mock.ANY, mock.ANY, 'fake_image_uuid',
+ 'fake_sr_path', 'fake_extra_header', **params)
@mock.patch.object(time, 'sleep')
@mock.patch.object(compute_utils, 'add_instance_fault_from_exc')
@@ -172,10 +239,11 @@ class TestGlanceStore(stubs.XenAPITestBaseNoDB):
mock_add_inst,
mock_time_sleep):
self.flags(num_retries=2, group='glance')
- params = self._get_upload_params()
+ params = self._get_params()
+ params.update(self._get_upload_params())
error_details = ["", "", "RetryableError", ""]
- error = self.session.XenAPI.Failure(details=error_details)
+ error = XenAPI.Failure(details=error_details)
with mock.patch.object(self.session, 'call_plugin_serialized',
side_effect=error) as mock_call_plugin:
@@ -206,10 +274,11 @@ class TestGlanceStore(stubs.XenAPITestBaseNoDB):
mock_add_inst,
mock_time_sleep):
self.flags(num_retries=2, group='glance')
- params = self._get_upload_params()
+ params = self._get_params()
+ params.update(self._get_upload_params())
error_details = ["", "task signaled", "", ""]
- error = self.session.XenAPI.Failure(details=error_details)
+ error = XenAPI.Failure(details=error_details)
# Note(johngarbutt) XenServer 6.1 and later has this error
error_details_v61 = ["", "signal: SIGTERM", "", ""]
diff --git a/nova/tests/unit/virt/xenapi/test_agent.py b/nova/tests/unit/virt/xenapi/test_agent.py
index 2069f5155a..8c77445c22 100644
--- a/nova/tests/unit/virt/xenapi/test_agent.py
+++ b/nova/tests/unit/virt/xenapi/test_agent.py
@@ -15,10 +15,11 @@
import base64
import time
-import uuid
import mock
+from os_xenapi.client import host_agent
from os_xenapi.client import XenAPI
+from oslo_utils import uuidutils
from nova import exception
from nova import test
@@ -169,7 +170,7 @@ class FileInjectionTestCase(AgentTestCaseBase):
b64_contents = base64.b64encode(b'contents')
agent.inject_file("path", "contents")
- mock_call_agent.assert_called_once_with('inject_file',
+ mock_call_agent.assert_called_once_with(host_agent.inject_file,
{'b64_contents': b64_contents,
'b64_path': b64_path})
@@ -197,35 +198,21 @@ class FileInjectionTestCase(AgentTestCaseBase):
mock_inject_file.assert_not_called()
-class FakeRebootException(Exception):
- details = ["", "", "", "asdf REBOOT: asdf"]
-
-
class RebootRetryTestCase(AgentTestCaseBase):
@mock.patch.object(agent, '_wait_for_new_dom_id')
def test_retry_on_reboot(self, mock_wait):
mock_session = mock.Mock()
-
- def fake_call_plugin(*args, **kwargs):
- if fake_call_plugin.called:
- return {"returncode": '0', "message": "done"}
- else:
- fake_call_plugin.called = True
- raise FakeRebootException()
-
- fake_call_plugin.called = False
- mock_session.XenAPI.Failure = FakeRebootException
mock_session.VM.get_domid.return_value = "fake_dom_id"
- mock_session.call_plugin.side_effect = fake_call_plugin
-
agent = self._create_agent(None, mock_session)
-
- result = agent._call_agent("asdf")
+ mock_method = mock.Mock().method()
+ mock_method.side_effect = [XenAPI.Failure(["REBOOT: fake"]),
+ {"returncode": '0', "message": "done"}]
+ result = agent._call_agent(mock_method)
self.assertEqual("done", result)
self.assertTrue(mock_session.VM.get_domid.called)
- self.assertEqual(2, mock_session.call_plugin.call_count)
+ self.assertEqual(2, mock_method.call_count)
mock_wait.assert_called_once_with(mock_session, self.vm_ref,
- "fake_dom_id", "asdf")
+ "fake_dom_id", mock_method)
@mock.patch.object(time, 'sleep')
@mock.patch.object(time, 'time')
@@ -267,10 +254,12 @@ class RebootRetryTestCase(AgentTestCaseBase):
mock_time.side_effect = fake_time
mock_session = mock.Mock()
mock_session.VM.get_domid.return_value = "old"
+ mock_method = mock.Mock().method()
+ mock_method.__name__ = "mock_method"
self.assertRaises(exception.AgentTimeout,
agent._wait_for_new_dom_id,
- mock_session, "vm_ref", "old", "method")
+ mock_session, "vm_ref", "old", mock_method)
self.assertEqual(4, mock_session.VM.get_domid.call_count)
@@ -286,7 +275,8 @@ class SetAdminPasswordTestCase(AgentTestCaseBase):
result = agent._exchange_key_with_agent()
- mock_call_agent.assert_called_once_with('key_init', {"pub": "4321"},
+ mock_call_agent.assert_called_once_with(host_agent.key_init,
+ {"pub": "4321"},
success_codes=['D0'],
ignore_errors=False)
result.compute_shared.assert_called_once_with(1234)
@@ -305,7 +295,7 @@ class SetAdminPasswordTestCase(AgentTestCaseBase):
agent_inst.set_admin_password("new_pass")
mock_dh.encrypt.assert_called_once_with("new_pass\n")
- mock_call_agent.assert_called_once_with('password',
+ mock_call_agent.assert_called_once_with(host_agent.password,
{'enc_pass': 'enc_pass'})
mock_save.assert_called_once_with("new_pass")
@@ -339,7 +329,7 @@ class UpgradeRequiredTestCase(test.NoDBTestCase):
self.assertTrue(agent.is_upgrade_required('1.2.3', '1.2.3.4'))
-@mock.patch.object(uuid, "uuid4")
+@mock.patch.object(uuidutils, 'generate_uuid')
class CallAgentTestCase(AgentTestCaseBase):
def test_call_agent_success(self, mock_uuid):
session = mock.Mock()
@@ -348,83 +338,88 @@ class CallAgentTestCase(AgentTestCaseBase):
session.VM.get_domid.return_value = '42'
mock_uuid.return_value = 1
- session.call_plugin.return_value = {'returncode': '4',
- 'message': "asdf\\r\\n"}
+ mock_method = mock.Mock().method()
+ mock_method.return_value = {'returncode': '4', 'message': "asdf\\r\\n"}
+ mock_method.__name__ = "mock_method"
self.assertEqual("asdf",
agent._call_agent(session, instance, "vm_ref",
- "method", addl_args, timeout=300,
+ mock_method, addl_args, timeout=300,
success_codes=['0', '4']))
- expected_args = {
- 'id': '1',
- 'dom_id': '42',
- 'timeout': '300',
- }
+ expected_args = {}
expected_args.update(addl_args)
- session.call_plugin.assert_called_once_with("agent.py", "method",
- expected_args)
+ mock_method.assert_called_once_with(session, 1, '42', 300,
+ **expected_args)
session.VM.get_domid.assert_called_once_with("vm_ref")
- def _call_agent_setup(self, session, mock_uuid,
+ def _call_agent_setup(self, session, mock_uuid, mock_method,
returncode='0', success_codes=None,
exception=None):
session.XenAPI.Failure = XenAPI.Failure
instance = {"uuid": "fake"}
+ addl_args = {"foo": "bar"}
session.VM.get_domid.return_value = "42"
mock_uuid.return_value = 1
if exception:
- session.call_plugin.side_effect = exception
+ mock_method.side_effect = exception
else:
- session.call_plugin.return_value = {'returncode': returncode,
- 'message': "asdf\\r\\n"}
-
- return agent._call_agent(session, instance, "vm_ref", "method",
- success_codes=success_codes)
-
- def _assert_agent_called(self, session, mock_uuid):
- expected_args = {
- 'id': '1',
- 'dom_id': '42',
- 'timeout': '30',
- }
- session.call_plugin.assert_called_once_with("agent.py", "method",
- expected_args)
+ mock_method.return_value = {'returncode': returncode,
+ 'message': "asdf\\r\\n"}
+
+ return agent._call_agent(session, instance, "vm_ref", mock_method,
+ addl_args, success_codes=success_codes)
+
+ def _assert_agent_called(self, session, mock_uuid, mock_method):
+ expected_args = {"foo": "bar"}
+ mock_uuid.assert_called_once_with()
+ mock_method.assert_called_once_with(session, 1, '42', 30,
+ **expected_args)
session.VM.get_domid.assert_called_once_with("vm_ref")
def test_call_agent_works_with_defaults(self, mock_uuid):
session = mock.Mock()
- self._call_agent_setup(session, mock_uuid)
- self._assert_agent_called(session, mock_uuid)
+ mock_method = mock.Mock().method()
+ mock_method.__name__ = "mock_method"
+ self._call_agent_setup(session, mock_uuid, mock_method)
+ self._assert_agent_called(session, mock_uuid, mock_method)
def test_call_agent_fails_with_timeout(self, mock_uuid):
session = mock.Mock()
+ mock_method = mock.Mock().method()
+ mock_method.__name__ = "mock_method"
self.assertRaises(exception.AgentTimeout, self._call_agent_setup,
- session, mock_uuid,
+ session, mock_uuid, mock_method,
exception=XenAPI.Failure(["TIMEOUT:fake"]))
- self._assert_agent_called(session, mock_uuid)
+ self._assert_agent_called(session, mock_uuid, mock_method)
def test_call_agent_fails_with_not_implemented(self, mock_uuid):
session = mock.Mock()
+ mock_method = mock.Mock().method()
+ mock_method.__name__ = "mock_method"
self.assertRaises(exception.AgentNotImplemented,
self._call_agent_setup,
- session, mock_uuid,
+ session, mock_uuid, mock_method,
exception=XenAPI.Failure(["NOT IMPLEMENTED:"]))
- self._assert_agent_called(session, mock_uuid)
+ self._assert_agent_called(session, mock_uuid, mock_method)
def test_call_agent_fails_with_other_error(self, mock_uuid):
session = mock.Mock()
+ mock_method = mock.Mock().method()
+ mock_method.__name__ = "mock_method"
self.assertRaises(exception.AgentError, self._call_agent_setup,
- session, mock_uuid,
+ session, mock_uuid, mock_method,
exception=XenAPI.Failure(["asdf"]))
- self._assert_agent_called(session, mock_uuid)
+ self._assert_agent_called(session, mock_uuid, mock_method)
def test_call_agent_fails_with_returned_error(self, mock_uuid):
session = mock.Mock()
+ mock_method = mock.Mock().method()
+ mock_method.__name__ = "mock_method"
self.assertRaises(exception.AgentError, self._call_agent_setup,
- session, mock_uuid, returncode='42')
- self._assert_agent_called(session, mock_uuid)
+ session, mock_uuid, mock_method, returncode='42')
+ self._assert_agent_called(session, mock_uuid, mock_method)
class XenAPIBasedAgent(AgentTestCaseBase):
diff --git a/nova/tests/unit/virt/xenapi/test_vif.py b/nova/tests/unit/virt/xenapi/test_vif.py
index 57a25043ab..e5f419ca96 100644
--- a/nova/tests/unit/virt/xenapi/test_vif.py
+++ b/nova/tests/unit/virt/xenapi/test_vif.py
@@ -23,6 +23,7 @@ from nova.tests.unit.virt.xenapi import stubs
from nova.virt.xenapi import network_utils
from nova.virt.xenapi import vif
from nova.virt.xenapi import vm_utils
+import os_xenapi
fake_vif = {
@@ -237,17 +238,14 @@ class XenAPIOpenVswitchDriverTestCase(XenVIFDriverTestBase):
@mock.patch.object(vif.XenAPIOpenVswitchDriver, '_delete_linux_bridge')
@mock.patch.object(vif.XenAPIOpenVswitchDriver, '_delete_linux_port')
- @mock.patch.object(vif.XenAPIOpenVswitchDriver, '_device_exists')
- @mock.patch.object(vif.XenAPIOpenVswitchDriver, '_ovs_del_br')
- @mock.patch.object(vif.XenAPIOpenVswitchDriver, '_ovs_del_port')
+ @mock.patch.object(os_xenapi.client.host_network, 'ovs_del_br')
+ @mock.patch.object(os_xenapi.client.host_network, 'ovs_del_port')
@mock.patch.object(network_utils, 'find_network_with_name_label')
def test_delete_network_and_bridge(self, mock_find_network,
mock_ovs_del_port, mock_ovs_del_br,
- mock_device_exists,
mock_delete_linux_port,
mock_delete_linux_bridge):
mock_find_network.return_value = 'fake_network'
- mock_device_exists.return_value = True
instance = {'name': 'fake_instance'}
vif = {'id': 'fake_vif'}
self._session.network = mock.Mock()
@@ -261,7 +259,7 @@ class XenAPIOpenVswitchDriverTestCase(XenVIFDriverTestBase):
self.assertTrue(mock_delete_linux_bridge.called)
self.assertTrue(mock_ovs_del_br.called)
- @mock.patch.object(vif.XenAPIOpenVswitchDriver, '_ovs_del_port')
+ @mock.patch.object(os_xenapi.client.host_network, 'ovs_del_port')
@mock.patch.object(network_utils, 'find_network_with_name_label',
return_value='fake_network')
def test_delete_network_and_bridge_destroy_exception(self,
@@ -283,9 +281,9 @@ class XenAPIOpenVswitchDriverTestCase(XenVIFDriverTestBase):
self.assertTrue(mock_ovs_del_port.called)
@mock.patch.object(vif.XenAPIOpenVswitchDriver, '_device_exists')
- @mock.patch.object(vif.XenAPIOpenVswitchDriver, '_brctl_add_if')
+ @mock.patch.object(os_xenapi.client.host_network, 'brctl_add_if')
@mock.patch.object(vif.XenAPIOpenVswitchDriver, '_create_linux_bridge')
- @mock.patch.object(vif.XenAPIOpenVswitchDriver, '_ovs_add_port')
+ @mock.patch.object(os_xenapi.client.host_network, 'ovs_add_port')
def test_post_start_actions(self, mock_ovs_add_port,
mock_create_linux_bridge,
mock_brctl_add_if, mock_device_exists):
@@ -317,9 +315,9 @@ class XenAPIOpenVswitchDriverTestCase(XenVIFDriverTestBase):
self.assertTrue(mock_brctl_add_if.called)
@mock.patch.object(vif.XenAPIOpenVswitchDriver, '_device_exists')
- @mock.patch.object(vif.XenAPIOpenVswitchDriver, '_brctl_add_if')
+ @mock.patch.object(os_xenapi.client.host_network, 'brctl_add_if')
@mock.patch.object(vif.XenAPIOpenVswitchDriver, '_create_linux_bridge')
- @mock.patch.object(vif.XenAPIOpenVswitchDriver, '_ovs_add_port')
+ @mock.patch.object(os_xenapi.client.host_network, 'ovs_add_port')
def test_post_start_actions_tap_exist(self, mock_ovs_add_port,
mock_create_linux_bridge,
mock_brctl_add_if, mock_device_exists):
diff --git a/nova/tests/unit/virt/xenapi/test_vm_utils.py b/nova/tests/unit/virt/xenapi/test_vm_utils.py
index a42dfe9932..707931cdcb 100644
--- a/nova/tests/unit/virt/xenapi/test_vm_utils.py
+++ b/nova/tests/unit/virt/xenapi/test_vm_utils.py
@@ -18,6 +18,7 @@ import contextlib
from eventlet import greenthread
import mock
from mox3 import mox
+import os_xenapi
from oslo_concurrency import lockutils
from oslo_concurrency import processutils
from oslo_config import fixture as config_fixture
@@ -1003,24 +1004,23 @@ class VDIOtherConfigTestCase(VMUtilsTestBase):
self.assertEqual(expected, other_config)
- def test_import_migrated_vhds(self):
+ @mock.patch.object(os_xenapi.client.vm_management, 'receive_vhd')
+ @mock.patch.object(vm_utils, 'scan_default_sr')
+ @mock.patch.object(vm_utils, 'get_sr_path')
+ def test_import_migrated_vhds(self, mock_sr_path, mock_scan_sr,
+ mock_recv_vhd):
# Migrated images should preserve the `other_config`
other_config = {}
def VDI_add_to_other_config(ref, key, value):
other_config[key] = value
- def call_plugin_serialized(*args, **kwargs):
- return {'root': {'uuid': 'aaaa-bbbb-cccc-dddd'}}
-
# Stubbing on the session object and not class so we don't pollute
# other tests
self.session.VDI_add_to_other_config = VDI_add_to_other_config
self.session.VDI_get_other_config = lambda vdi: {}
- self.session.call_plugin_serialized = call_plugin_serialized
- self.stubs.Set(vm_utils, 'get_sr_path', lambda *a, **k: None)
- self.stubs.Set(vm_utils, 'scan_default_sr', lambda *a, **k: None)
+ mock_sr_path.return_value = {'root': {'uuid': 'aaaa-bbbb-cccc-dddd'}}
vm_utils._import_migrated_vhds(self.session, self.fake_instance,
"disk_label", "root", "vdi_label")
@@ -1029,6 +1029,11 @@ class VDIOtherConfigTestCase(VMUtilsTestBase):
'nova_instance_uuid': 'aaaa-bbbb-cccc-dddd'}
self.assertEqual(expected, other_config)
+ mock_scan_sr.assert_called_once_with(self.session)
+ mock_recv_vhd.assert_called_with(
+ self.session, "disk_label",
+ {'root': {'uuid': 'aaaa-bbbb-cccc-dddd'}}, mock.ANY)
+ mock_sr_path.assert_called_once_with(self.session)
class GenerateDiskTestCase(VMUtilsTestBase):
@@ -1367,7 +1372,9 @@ class CreateKernelRamdiskTestCase(VMUtilsTestBase):
self.session, self.instance, self.name_label)
self.assertEqual((None, None), result)
- def test_create_kernel_and_ramdisk_create_both_cached(self):
+ @mock.patch.object(os_xenapi.client.disk_management,
+ 'create_kernel_ramdisk')
+ def test_create_kernel_and_ramdisk_create_both_cached(self, mock_ramdisk):
kernel_id = "kernel"
ramdisk_id = "ramdisk"
self.instance["kernel_id"] = kernel_id
@@ -1377,22 +1384,22 @@ class CreateKernelRamdiskTestCase(VMUtilsTestBase):
args_kernel['cached-image'] = kernel_id
args_kernel['new-image-uuid'] = "fake_uuid1"
uuidutils.generate_uuid().AndReturn("fake_uuid1")
- self.session.call_plugin('kernel.py', 'create_kernel_ramdisk',
- args_kernel).AndReturn("k")
+ mock_ramdisk.side_effect = ["k", "r"]
args_ramdisk = {}
args_ramdisk['cached-image'] = ramdisk_id
args_ramdisk['new-image-uuid'] = "fake_uuid2"
uuidutils.generate_uuid().AndReturn("fake_uuid2")
- self.session.call_plugin('kernel.py', 'create_kernel_ramdisk',
- args_ramdisk).AndReturn("r")
self.mox.ReplayAll()
result = vm_utils.create_kernel_and_ramdisk(self.context,
self.session, self.instance, self.name_label)
self.assertEqual(("k", "r"), result)
- def test_create_kernel_and_ramdisk_create_kernel_not_cached(self):
+ @mock.patch.object(os_xenapi.client.disk_management,
+ 'create_kernel_ramdisk')
+ def test_create_kernel_and_ramdisk_create_kernel_not_cached(self,
+ mock_ramdisk):
kernel_id = "kernel"
self.instance["kernel_id"] = kernel_id
@@ -1400,8 +1407,7 @@ class CreateKernelRamdiskTestCase(VMUtilsTestBase):
args_kernel['cached-image'] = kernel_id
args_kernel['new-image-uuid'] = "fake_uuid1"
uuidutils.generate_uuid().AndReturn("fake_uuid1")
- self.session.call_plugin('kernel.py', 'create_kernel_ramdisk',
- args_kernel).AndReturn("")
+ mock_ramdisk.return_value = ""
kernel = {"kernel": {"file": "k"}}
vm_utils._fetch_disk_image(self.context, self.session, self.instance,
@@ -1423,8 +1429,6 @@ class CreateKernelRamdiskTestCase(VMUtilsTestBase):
if cache_images == 'all':
uuidutils.generate_uuid().AndReturn("fake_uuid1")
- self.session.call_plugin('kernel.py', 'create_kernel_ramdisk',
- args_kernel).AndReturn("cached_image")
else:
kernel = {"kernel": {"file": "new_image", "uuid": None}}
vm_utils._fetch_disk_image(self.context, self.session,
@@ -1446,8 +1450,13 @@ class CreateKernelRamdiskTestCase(VMUtilsTestBase):
self.assertEqual(result, {"kernel":
{"file": "new_image", "uuid": None}})
- def test_create_kernel_image_cached_config(self):
+ @mock.patch.object(os_xenapi.client.disk_management,
+ 'create_kernel_ramdisk')
+ def test_create_kernel_image_cached_config(self, mock_ramdisk):
+ mock_ramdisk.return_value = "cached_image"
self._test_create_kernel_image('all')
+ mock_ramdisk.assert_called_once_with(self.session, "kernel",
+ "fake_uuid1")
def test_create_kernel_image_uncached_config(self):
self._test_create_kernel_image('none')
@@ -2020,14 +2029,15 @@ class ImportMigratedDisksTestCase(VMUtilsTestBase):
vm_utils._import_migrate_ephemeral_disks("s", instance)
mock_get_sizes.assert_called_once_with(4000)
+ @mock.patch.object(os_xenapi.client.vm_management, 'receive_vhd')
@mock.patch.object(vm_utils, '_set_vdi_info')
@mock.patch.object(vm_utils, 'scan_default_sr')
@mock.patch.object(vm_utils, 'get_sr_path')
def test_import_migrated_vhds(self, mock_get_sr_path, mock_scan_sr,
- mock_set_info):
+ mock_set_info, mock_recv_vhd):
session = mock.Mock()
instance = {"uuid": "uuid"}
- session.call_plugin_serialized.return_value = {"root": {"uuid": "a"}}
+ mock_recv_vhd.return_value = {"root": {"uuid": "a"}}
session.call_xenapi.return_value = "vdi_ref"
mock_get_sr_path.return_value = "sr_path"
@@ -2037,9 +2047,8 @@ class ImportMigratedDisksTestCase(VMUtilsTestBase):
expected = {'uuid': "a", 'ref': "vdi_ref"}
self.assertEqual(expected, result)
mock_get_sr_path.assert_called_once_with(session)
- session.call_plugin_serialized.assert_called_once_with('migration.py',
- 'move_vhds_into_sr', instance_uuid='chain_label',
- sr_path='sr_path', uuid_stack=mock.ANY)
+ mock_recv_vhd.assert_called_once_with(session, 'chain_label',
+ 'sr_path', mock.ANY)
mock_scan_sr.assert_called_once_with(session)
session.call_xenapi.assert_called_once_with('VDI.get_by_uuid', 'a')
mock_set_info.assert_called_once_with(session, 'vdi_ref', 'disk_type',
@@ -2061,33 +2070,42 @@ class MigrateVHDTestCase(VMUtilsTestBase):
'migration.py', 'transfer_vhd', instance_uuid=label, host="dest",
vdi_uuid="vdi_uuid", sr_path="sr_path", seq_num=2)
- def test_migrate_vhd_root(self):
+ @mock.patch.object(os_xenapi.client.vm_management, 'transfer_vhd')
+ def test_migrate_vhd_root(self, mock_trans_vhd):
session = mock.Mock()
instance = {"uuid": "a"}
vm_utils.migrate_vhd(session, instance, "vdi_uuid", "dest",
"sr_path", 2)
- self._assert_transfer_called(session, "a")
+ mock_trans_vhd.assert_called_once_with(session, "a",
+ "dest", "vdi_uuid", "sr_path",
+ 2)
- def test_migrate_vhd_ephemeral(self):
+ @mock.patch.object(os_xenapi.client.vm_management, 'transfer_vhd')
+ def test_migrate_vhd_ephemeral(self, mock_trans_vhd):
session = mock.Mock()
instance = {"uuid": "a"}
vm_utils.migrate_vhd(session, instance, "vdi_uuid", "dest",
"sr_path", 2, 2)
- self._assert_transfer_called(session, "a_ephemeral_2")
+ mock_trans_vhd.assert_called_once_with(session, "a_ephemeral_2",
+ "dest", "vdi_uuid", "sr_path",
+ 2)
- def test_migrate_vhd_converts_exceptions(self):
+ @mock.patch.object(os_xenapi.client.vm_management, 'transfer_vhd')
+ def test_migrate_vhd_converts_exceptions(self, mock_trans_vhd):
session = mock.Mock()
session.XenAPI.Failure = test.TestingException
- session.call_plugin_serialized.side_effect = test.TestingException()
+ mock_trans_vhd.side_effect = test.TestingException()
instance = {"uuid": "a"}
self.assertRaises(exception.MigrationError, vm_utils.migrate_vhd,
session, instance, "vdi_uuid", "dest", "sr_path", 2)
- self._assert_transfer_called(session, "a")
+ mock_trans_vhd.assert_called_once_with(session, "a",
+ "dest", "vdi_uuid", "sr_path",
+ 2)
class StripBaseMirrorTestCase(VMUtilsTestBase):
diff --git a/nova/tests/unit/virt/xenapi/test_vmops.py b/nova/tests/unit/virt/xenapi/test_vmops.py
index 0ff4d434b9..83cc845674 100644
--- a/nova/tests/unit/virt/xenapi/test_vmops.py
+++ b/nova/tests/unit/virt/xenapi/test_vmops.py
@@ -22,6 +22,7 @@ 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
@@ -1307,35 +1308,43 @@ class XenstoreCallsTestCase(VMOpsTestBase):
from vmops.
"""
- @mock.patch.object(vmops.VMOps, '_make_plugin_call')
- def test_read_from_xenstore(self, fake_xapi_call):
- fake_xapi_call.return_value = "fake_xapi_return"
+ @mock.patch.object(vmops.VMOps, '_get_dom_id')
+ @mock.patch.object(host_xenstore, 'read_record')
+ def test_read_from_xenstore(self, mock_read_record, mock_dom_id):
+ mock_read_record.return_value = "fake_xapi_return"
+ mock_dom_id.return_value = "fake_dom_id"
fake_instance = {"name": "fake_instance"}
path = "attr/PVAddons/MajorVersion"
self.assertEqual("fake_xapi_return",
self.vmops._read_from_xenstore(fake_instance, path,
vm_ref="vm_ref"))
-
- @mock.patch.object(vmops.VMOps, '_make_plugin_call')
- def test_read_from_xenstore_ignore_missing_path(self, fake_xapi_call):
+ mock_dom_id.assert_called_once_with(fake_instance, "vm_ref")
+
+ @mock.patch.object(vmops.VMOps, '_get_dom_id')
+ @mock.patch.object(host_xenstore, 'read_record')
+ def test_read_from_xenstore_ignore_missing_path(self, mock_read_record,
+ mock_dom_id):
+ mock_read_record.return_value = "fake_xapi_return"
+ mock_dom_id.return_value = "fake_dom_id"
fake_instance = {"name": "fake_instance"}
path = "attr/PVAddons/MajorVersion"
self.vmops._read_from_xenstore(fake_instance, path, vm_ref="vm_ref")
- fake_xapi_call.assert_called_once_with('xenstore.py', 'read_record',
- fake_instance, vm_ref="vm_ref",
- path=path,
- ignore_missing_path='True')
-
- @mock.patch.object(vmops.VMOps, '_make_plugin_call')
- def test_read_from_xenstore_missing_path(self, fake_xapi_call):
+ mock_read_record.assert_called_once_with(
+ self._session, "fake_dom_id", path, ignore_missing_path=True)
+
+ @mock.patch.object(vmops.VMOps, '_get_dom_id')
+ @mock.patch.object(host_xenstore, 'read_record')
+ def test_read_from_xenstore_missing_path(self, mock_read_record,
+ mock_dom_id):
+ mock_read_record.return_value = "fake_xapi_return"
+ mock_dom_id.return_value = "fake_dom_id"
fake_instance = {"name": "fake_instance"}
path = "attr/PVAddons/MajorVersion"
self.vmops._read_from_xenstore(fake_instance, path, vm_ref="vm_ref",
ignore_missing_path=False)
- fake_xapi_call.assert_called_once_with('xenstore.py', 'read_record',
- fake_instance, vm_ref="vm_ref",
- path=path,
- ignore_missing_path='False')
+ mock_read_record.assert_called_once_with(self._session, "fake_dom_id",
+ path,
+ ignore_missing_path=False)
class LiveMigrateTestCase(VMOpsTestBase):
diff --git a/nova/tests/unit/virt/xenapi/test_xenapi.py b/nova/tests/unit/virt/xenapi/test_xenapi.py
index 59642369ed..a980edc02c 100644
--- a/nova/tests/unit/virt/xenapi/test_xenapi.py
+++ b/nova/tests/unit/virt/xenapi/test_xenapi.py
@@ -24,6 +24,7 @@ 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
@@ -1694,18 +1695,29 @@ class XenAPIMigrateInstance(stubs.XenAPITestBase):
instance.create()
return instance
+ @mock.patch.object(vmops.VMOps, '_migrate_disk_resizing_up')
+ @mock.patch.object(vm_utils, 'get_sr_path')
+ @mock.patch.object(vm_utils, 'lookup')
@mock.patch.object(volume_utils, 'is_booted_from_volume')
- def test_migrate_disk_and_power_off(self, mock_boot):
+ def test_migrate_disk_and_power_off(self, mock_boot_from_volume,
+ mock_lookup, mock_sr_path,
+ mock_migrate):
instance = self._create_instance()
xenapi_fake.create_vm(instance['name'], 'Running')
flavor = fake_flavor.fake_flavor_obj(self.context, root_gb=80,
ephemeral_gb=0)
conn = xenapi_conn.XenAPIDriver(fake.FakeVirtAPI(), False)
- vm_ref = vm_utils.lookup(conn._session, instance['name'])
- volume_utils.is_booted_from_volume(conn._session, vm_ref)
+ mock_boot_from_volume.return_value = True
+ mock_lookup.return_value = 'fake_vm_ref'
+ mock_sr_path.return_value = 'fake_sr_path'
conn.migrate_disk_and_power_off(self.context, instance,
'127.0.0.1', flavor, None)
- mock_boot.assert_any_call(conn._session, vm_ref)
+ mock_lookup.assert_called_once_with(conn._session, instance['name'],
+ False)
+ mock_sr_path.assert_called_once_with(conn._session)
+ mock_migrate.assert_called_once_with(self.context, instance,
+ '127.0.0.1', 'fake_vm_ref',
+ 'fake_sr_path')
def test_migrate_disk_and_power_off_passes_exceptions(self):
instance = self._create_instance()
@@ -1735,20 +1747,31 @@ class XenAPIMigrateInstance(stubs.XenAPITestBase):
self.context, instance,
'fake_dest', flavor, None)
+ @mock.patch.object(vmops.VMOps, '_migrate_disk_resizing_up')
+ @mock.patch.object(vm_utils, 'get_sr_path')
+ @mock.patch.object(vm_utils, 'lookup')
@mock.patch.object(volume_utils, 'is_booted_from_volume')
- def test_migrate_disk_and_power_off_with_zero_gb_old_and_new_works(self,
- mock_boot):
+ def test_migrate_disk_and_power_off_with_zero_gb_old_and_new_works(
+ self, mock_boot_from_volume, mock_lookup, mock_sr_path,
+ mock_migrate):
flavor = fake_flavor.fake_flavor_obj(self.context, root_gb=0,
ephemeral_gb=0)
instance = self._create_instance(root_gb=0, ephemeral_gb=0)
instance.flavor.root_gb = 0
instance.flavor.ephemeral_gb = 0
xenapi_fake.create_vm(instance['name'], 'Running')
+ mock_boot_from_volume.return_value = True
+ mock_lookup.return_value = 'fake_vm_ref'
+ mock_sr_path.return_value = 'fake_sr_path'
conn = xenapi_conn.XenAPIDriver(fake.FakeVirtAPI(), False)
- vm_ref = vm_utils.lookup(conn._session, instance['name'])
conn.migrate_disk_and_power_off(self.context, instance,
'127.0.0.1', flavor, None)
- mock_boot.assert_any_call(conn._session, vm_ref)
+ mock_lookup.assert_called_once_with(conn._session, instance['name'],
+ False)
+ mock_sr_path.assert_called_once_with(conn._session)
+ mock_migrate.assert_called_once_with(self.context, instance,
+ '127.0.0.1', 'fake_vm_ref',
+ 'fake_sr_path')
def _test_revert_migrate(self, power_on):
instance = create_instance_with_system_metadata(self.context,
@@ -2234,12 +2257,15 @@ class XenAPIHostTestCase(stubs.XenAPITestBase):
stats = self.conn.host_state.get_host_stats(False)
self.assertEqual("SOMERETURNVALUE", stats['supported_instances'])
- def test_update_stats_caches_hostname(self):
- self.mox.StubOutWithMock(host, 'call_xenhost')
- self.mox.StubOutWithMock(vm_utils, 'scan_default_sr')
- self.mox.StubOutWithMock(vm_utils, 'list_vms')
- self.mox.StubOutWithMock(self.conn._session, 'call_xenapi')
- self.mox.StubOutWithMock(host.HostState, 'get_disk_used')
+ @mock.patch.object(host.HostState, 'get_disk_used')
+ @mock.patch.object(host.HostState, '_get_passthrough_devices')
+ @mock.patch.object(jsonutils, 'loads')
+ @mock.patch.object(vm_utils, 'list_vms')
+ @mock.patch.object(vm_utils, 'scan_default_sr')
+ @mock.patch.object(host_management, 'get_host_data')
+ def test_update_stats_caches_hostname(self, mock_host_data, mock_scan_sr,
+ mock_list_vms, mock_loads,
+ mock_devices, mock_dis_used):
data = {'disk_total': 0,
'disk_used': 0,
'disk_available': 0,
@@ -2253,23 +2279,26 @@ class XenAPIHostTestCase(stubs.XenAPITestBase):
'physical_utilisation': 0,
'virtual_allocation': 0,
}
-
- for i in range(3):
- host.call_xenhost(mox.IgnoreArg(), 'host_data', {}).AndReturn(data)
- vm_utils.scan_default_sr(self.conn._session).AndReturn("ref")
- vm_utils.list_vms(self.conn._session).AndReturn([])
- self.conn._session.call_xenapi('SR.get_record', "ref").AndReturn(
- sr_rec)
- host.HostState.get_disk_used("ref").AndReturn((0, 0))
- if i == 2:
- # On the third call (the second below) change the hostname
- data = dict(data, host_hostname='bar')
-
- self.mox.ReplayAll()
- stats = self.conn.host_state.get_host_stats(refresh=True)
- self.assertEqual('foo', stats['hypervisor_hostname'])
- stats = self.conn.host_state.get_host_stats(refresh=True)
- self.assertEqual('foo', stats['hypervisor_hostname'])
+ mock_loads.return_value = data
+ mock_host_data.return_value = data
+ mock_scan_sr.return_value = 'ref'
+ mock_list_vms.return_value = []
+ mock_devices.return_value = "dev1"
+ mock_dis_used.return_value = (0, 0)
+ self.conn._session = mock.Mock()
+ with mock.patch.object(self.conn._session.SR, 'get_record') \
+ as mock_record:
+ mock_record.return_value = sr_rec
+ stats = self.conn.host_state.get_host_stats(refresh=True)
+ self.assertEqual('foo', stats['hypervisor_hostname'])
+ self.assertEqual(2, mock_loads.call_count)
+ self.assertEqual(2, mock_host_data.call_count)
+ self.assertEqual(2, mock_scan_sr.call_count)
+ self.assertEqual(2, mock_devices.call_count)
+ mock_loads.assert_called_with(data)
+ mock_host_data.assert_called_with(self.conn._session)
+ mock_scan_sr.assert_called_with(self.conn._session)
+ mock_devices.assert_called_with()
@mock.patch.object(host.HostState, 'update_status')