]> review.fuel-infra Code Review - openstack-build/cinder-build.git/commitdiff
VMware:Unquote folder name for folder exists check
authorVipin Balachandran <vbala@vmware.com>
Thu, 14 Aug 2014 09:39:40 +0000 (15:09 +0530)
committerVipin Balachandran <vbala@vmware.com>
Mon, 29 Sep 2014 12:33:19 +0000 (18:03 +0530)
vCenter server escapes special characters in the folder name using URL
encoding and returns back the encoded string while querying. This causes
the check for folder existence to return false. Therefore, folder
creation is reattempted which eventually fails. This patch fixes the
problem by decoding the folder name returned by vCenter before
comparison.

Change-Id: I40aa6f42ea0d85fbfcb40970c55b20e13ea46522
Closes-Bug: #1356794

cinder/tests/test_vmware_volumeops.py
cinder/volume/drivers/vmware/volumeops.py

index 4288e52c17970be170ca7bd0de0e9b6fec9ad9f0..7e2caaf8f33b97df1d840e0eaa9fd614bd578393 100644 (file)
@@ -454,6 +454,47 @@ class VolumeOpsTestCase(test.TestCase):
         # Clear side effects.
         self.session.invoke_api.side_effect = None
 
+    def test_create_folder_with_special_characters(self):
+        """Test create_folder with names containing special characters."""
+        # Test folder already exists case.
+        child_entity_1 = mock.Mock(_type='Folder')
+        child_entity_1_name = 'cinder-volumes'
+
+        child_entity_2 = mock.Mock(_type='Folder')
+        child_entity_2_name = '%2fcinder-volumes'
+
+        prop_val = mock.Mock(ManagedObjectReference=[child_entity_1,
+                                                     child_entity_2])
+        self.session.invoke_api.side_effect = [prop_val,
+                                               child_entity_1_name,
+                                               child_entity_2_name]
+
+        parent_folder = mock.sentinel.parent_folder
+        child_name = '/cinder-volumes'
+        ret = self.vops.create_folder(parent_folder, child_name)
+
+        self.assertEqual(child_entity_2, ret)
+
+        # Test non-existing folder case.
+        child_entity_2_name = '%25%25cinder-volumes'
+        new_child_folder = mock.sentinel.new_child_folder
+        self.session.invoke_api.side_effect = [prop_val,
+                                               child_entity_1_name,
+                                               child_entity_2_name,
+                                               new_child_folder]
+
+        child_name = '%cinder-volumes'
+        ret = self.vops.create_folder(parent_folder, child_name)
+
+        self.assertEqual(new_child_folder, ret)
+        self.session.invoke_api.assert_called_with(self.session.vim,
+                                                   'CreateFolder',
+                                                   parent_folder,
+                                                   name=child_name)
+
+        # Reset side effects.
+        self.session.invoke_api.side_effect = None
+
     def test_create_disk_backing_thin(self):
         backing = mock.Mock()
         del backing.eagerlyScrub
index 307b2f33af745d6dd6663aca6241002c69919d80..775314624afc76d5998548f59dcd7bc9d35033f9 100644 (file)
@@ -17,6 +17,8 @@
 Implements operations on volumes residing on VMware datastores.
 """
 
+import urllib
+
 from cinder.i18n import _
 from cinder.openstack.common import log as logging
 from cinder.openstack.common import units
@@ -536,9 +538,10 @@ class VMwareVolumeOps(object):
             if child_entity._type != 'Folder':
                 continue
             child_entity_name = self.get_entity_name(child_entity)
-            if child_entity_name == child_folder_name:
-                LOG.debug("Child folder already present: %s." %
-                          child_entity)
+            if child_entity_name and (urllib.unquote(child_entity_name) ==
+                                      child_folder_name):
+                LOG.debug("Child folder: %s already present.",
+                          child_folder_name)
                 return child_entity
 
         # Need to create the child folder