diff --git a/nova/tests/unit/virt/libvirt/test_driver.py b/nova/tests/unit/virt/libvirt/test_driver.py
index a58cd90958ec..392e0e8b94b1 100644
--- a/nova/tests/unit/virt/libvirt/test_driver.py
+++ b/nova/tests/unit/virt/libvirt/test_driver.py
@@ -14764,7 +14764,12 @@ class LibvirtConnTestCase(test.NoDBTestCase,
fake_xml = "this is a test"
def fake_defineXML(xml):
- self.assertEqual(fake_xml, xml)
+ # In py2 env, xml is encoded in write_instance_config use
+ # encodeutils.safe_encode, it will be decode text before encoding
+ if six.PY2:
+ self.assertEqual(fake_safe_decode(fake_xml), xml)
+ else:
+ self.assertEqual(fake_xml, xml)
raise fakelibvirt.libvirtError('virDomainDefineXML() failed')
def fake_safe_decode(text, *args, **kwargs):
@@ -15599,20 +15604,22 @@ class LibvirtConnTestCase(test.NoDBTestCase,
create=True) as mock_define:
srcfile = "/first/path"
dstfile = "/second/path"
+ orig_xml = six.text_type(mock.sentinel.orig_xml)
+ new_xml = six.text_type(mock.sentinel.new_xml)
- mock_dom.XMLDesc.return_value = mock.sentinel.orig_xml
+ mock_dom.XMLDesc.return_value = orig_xml
mock_dom.isPersistent.return_value = True
def fake_rebase_success(*args, **kwargs):
# Make sure the XML is set after the rebase so we know
# get_xml_desc was called after the update.
- mock_dom.XMLDesc.return_value = mock.sentinel.new_xml
+ mock_dom.XMLDesc.return_value = new_xml
if not fail:
mock_dom.blockRebase.side_effect = fake_rebase_success
# If the swap succeeds, make sure we use the new XML to
# redefine the domain.
- expected_xml = mock.sentinel.new_xml
+ expected_xml = new_xml
else:
if resize:
mock_dom.blockResize.side_effect = test.TestingException()
@@ -15622,7 +15629,7 @@ class LibvirtConnTestCase(test.NoDBTestCase,
expected_exception = exception.VolumeRebaseFailed
# If the swap fails, make sure we use the original domain XML
# to redefine the domain.
- expected_xml = mock.sentinel.orig_xml
+ expected_xml = orig_xml
# Run the swap volume code.
mock_conf = mock.MagicMock(source_type=source_type,
diff --git a/nova/tests/unit/virt/libvirt/test_host.py b/nova/tests/unit/virt/libvirt/test_host.py
index 6fba2ac082f9..7e9cdbf6756a 100644
--- a/nova/tests/unit/virt/libvirt/test_host.py
+++ b/nova/tests/unit/virt/libvirt/test_host.py
@@ -775,6 +775,31 @@ Active: 8381604 kB
mock_defineXML.assert_called_once_with(fake_dom_xml)
self.assertIsInstance(guest, libvirt_guest.Guest)
+ def test_write_instance_config_unicode(self):
+ fake_dom_xml = u"""
+
+ cef19ce0-0ca2-11df-855d-b19fbce37686
+
+
+
+
+
+
+ """
+
+ def emulate_defineXML(xml):
+ conn = self.host.get_connection()
+ # Emulate the decoding behavior of defineXML in Python2
+ if six.PY2:
+ xml = xml.decode("utf-8")
+ dom = fakelibvirt.Domain(conn, xml, False)
+ return dom
+ with mock.patch.object(fakelibvirt.virConnect, "defineXML"
+ ) as mock_defineXML:
+ mock_defineXML.side_effect = emulate_defineXML
+ guest = self.host.write_instance_config(fake_dom_xml)
+ self.assertIsInstance(guest, libvirt_guest.Guest)
+
@mock.patch.object(fakelibvirt.virConnect, "nodeDeviceLookupByName")
def test_device_lookup_by_name(self, mock_nodeDeviceLookupByName):
self.host.device_lookup_by_name("foo")
diff --git a/nova/virt/libvirt/host.py b/nova/virt/libvirt/host.py
index 7f476a9ace04..3802cb984b00 100644
--- a/nova/virt/libvirt/host.py
+++ b/nova/virt/libvirt/host.py
@@ -38,6 +38,7 @@ from eventlet import greenthread
from eventlet import patcher
from eventlet import tpool
from oslo_log import log as logging
+from oslo_utils import encodeutils
from oslo_utils import excutils
from oslo_utils import importutils
from oslo_utils import units
@@ -823,6 +824,8 @@ class Host(object):
:returns: an instance of Guest
"""
+ if six.PY2:
+ xml = encodeutils.safe_encode(xml)
domain = self.get_connection().defineXML(xml)
return libvirt_guest.Guest(domain)