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)