Merge "Make parameter list generation consistent using urlencode()."
diff --git a/tempest/services/compute/json/flavors_client.py b/tempest/services/compute/json/flavors_client.py
index 01708a2..dc825df 100644
--- a/tempest/services/compute/json/flavors_client.py
+++ b/tempest/services/compute/json/flavors_client.py
@@ -17,6 +17,7 @@
 
 from tempest.common.rest_client import RestClient
 import json
+import urllib
 
 
 class FlavorsClientJSON(RestClient):
@@ -28,12 +29,8 @@
 
     def list_flavors(self, params=None):
         url = 'flavors'
-        if params is not None:
-            param_list = []
-            for param, value in params.iteritems():
-                param_list.append("%s=%s&" % (param, value))
-
-            url = "flavors?" + "".join(param_list)
+        if params:
+            url += '?%s' % urllib.urlencode(params)
 
         resp, body = self.get(url)
         body = json.loads(body)
@@ -41,12 +38,8 @@
 
     def list_flavors_with_detail(self, params=None):
         url = 'flavors/detail'
-        if params is not None:
-            param_list = []
-            for param, value in params.iteritems():
-                param_list.append("%s=%s&" % (param, value))
-
-            url = "flavors/detail?" + "".join(param_list)
+        if params:
+            url += '?%s' % urllib.urlencode(params)
 
         resp, body = self.get(url)
         body = json.loads(body)
diff --git a/tempest/services/compute/json/floating_ips_client.py b/tempest/services/compute/json/floating_ips_client.py
index 6219f34..1303c52 100644
--- a/tempest/services/compute/json/floating_ips_client.py
+++ b/tempest/services/compute/json/floating_ips_client.py
@@ -18,6 +18,7 @@
 from tempest.common.rest_client import RestClient
 from tempest import exceptions
 import json
+import urllib
 
 
 class FloatingIPsClientJSON(RestClient):
@@ -29,11 +30,9 @@
     def list_floating_ips(self, params=None):
         """Returns a list of all floating IPs filtered by any parameters"""
         url = 'os-floating-ips'
-        if params is not None:
-            param_list = []
-            for param, value in params.iteritems():
-                param_list.append("%s=%s" % (param, value))
-            url += '?' + ' &'.join(param_list)
+        if params:
+            url += '?%s' % urllib.urlencode(params)
+
         resp, body = self.get(url)
         body = json.loads(body)
         return resp, body['floating_ips']
diff --git a/tempest/services/compute/json/images_client.py b/tempest/services/compute/json/images_client.py
index 102590c..999d6cb 100644
--- a/tempest/services/compute/json/images_client.py
+++ b/tempest/services/compute/json/images_client.py
@@ -19,6 +19,7 @@
 from tempest import exceptions
 import json
 import time
+import urllib
 
 
 class ImagesClientJSON(RestClient):
@@ -50,12 +51,8 @@
     def list_images(self, params=None):
         """Returns a list of all images filtered by any parameters"""
         url = 'images'
-        if params is not None:
-            param_list = []
-            for param, value in params.iteritems():
-                param_list.append("%s=%s&" % (param, value))
-
-            url = "images?" + "".join(param_list)
+        if params:
+            url += '?%s' % urllib.urlencode(params)
 
         resp, body = self.get(url)
         body = json.loads(body)
@@ -64,12 +61,8 @@
     def list_images_with_detail(self, params=None):
         """Returns a detailed list of images filtered by any parameters"""
         url = 'images/detail'
-        if params is not None:
-            param_list = []
-            for param, value in params.iteritems():
-                param_list.append("%s=%s&" % (param, value))
-
-            url = "images/detail?" + "".join(param_list)
+        if params:
+            url += '?%s' % urllib.urlencode(params)
 
         resp, body = self.get(url)
         body = json.loads(body)
diff --git a/tempest/services/compute/json/security_groups_client.py b/tempest/services/compute/json/security_groups_client.py
index 9d8de23..cf8fed7 100644
--- a/tempest/services/compute/json/security_groups_client.py
+++ b/tempest/services/compute/json/security_groups_client.py
@@ -17,6 +17,7 @@
 
 from tempest.common.rest_client import RestClient
 import json
+import urllib
 
 
 class SecurityGroupsClientJSON(RestClient):
@@ -31,12 +32,8 @@
         """List all security groups for a user"""
 
         url = 'os-security-groups'
-        if params is not None:
-            param_list = []
-            for param, value in params.iteritems():
-                param_list.append("%s=%s" % (param, value))
-
-            url += '?' + ' &'.join(param_list)
+        if params:
+            url += '?%s' % urllib.urlencode(params)
 
         resp, body = self.get(url)
         body = json.loads(body)
diff --git a/tempest/services/compute/json/servers_client.py b/tempest/services/compute/json/servers_client.py
index 94fe637..97ef78e 100644
--- a/tempest/services/compute/json/servers_client.py
+++ b/tempest/services/compute/json/servers_client.py
@@ -19,6 +19,7 @@
 from tempest.common.rest_client import RestClient
 import json
 import time
+import urllib
 
 
 class ServersClientJSON(RestClient):
@@ -121,12 +122,8 @@
         """Lists all servers for a user"""
 
         url = 'servers'
-        if params is not None:
-            param_list = []
-            for param, value in params.iteritems():
-                param_list.append("%s=%s&" % (param, value))
-
-            url = "servers?" + "".join(param_list)
+        if params:
+            url += '?%s' % urllib.urlencode(params)
 
         resp, body = self.get(url)
         body = json.loads(body)
@@ -136,12 +133,8 @@
         """Lists all servers in detail for a user"""
 
         url = 'servers/detail'
-        if params is not None:
-            param_list = []
-            for param, value in params.iteritems():
-                param_list.append("%s=%s&" % (param, value))
-
-            url = "servers/detail?" + "".join(param_list)
+        if params:
+            url += '?%s' % urllib.urlencode(params)
 
         resp, body = self.get(url)
         body = json.loads(body)
diff --git a/tempest/services/compute/json/volumes_extensions_client.py b/tempest/services/compute/json/volumes_extensions_client.py
index 240bcfe..1c5d525 100644
--- a/tempest/services/compute/json/volumes_extensions_client.py
+++ b/tempest/services/compute/json/volumes_extensions_client.py
@@ -19,6 +19,7 @@
 from tempest.common.rest_client import RestClient
 import json
 import time
+import urllib
 
 
 class VolumesExtensionsClientJSON(RestClient):
@@ -34,12 +35,8 @@
     def list_volumes(self, params=None):
         """List all the volumes created"""
         url = 'os-volumes'
-        if params is not None:
-            param_list = []
-            for param, value in params.iteritems():
-                param_list.append("%s=%s&" % (param, value))
-
-            url += '?' + ' '.join(param_list)
+        if params:
+            url += '?%s' % urllib.urlencode(params)
 
         resp, body = self.get(url)
         body = json.loads(body)
@@ -48,12 +45,8 @@
     def list_volumes_with_detail(self, params=None):
         """List all the details of volumes"""
         url = 'os-volumes/detail'
-        if params is not None:
-            param_list = []
-            for param, value in params.iteritems():
-                param_list.append("%s=%s&" % (param, value))
-
-            url = '?' + ' '.join(param_list)
+        if params:
+            url += '?%s' % urllib.urlencode(params)
 
         resp, body = self.get(url)
         body = json.loads(body)
diff --git a/tempest/services/compute/xml/flavors_client.py b/tempest/services/compute/xml/flavors_client.py
index 63ce267..1dc34a5 100644
--- a/tempest/services/compute/xml/flavors_client.py
+++ b/tempest/services/compute/xml/flavors_client.py
@@ -63,7 +63,7 @@
         return [self._format_flavor(xml_to_json(x)) for x in node]
 
     def _list_flavors(self, url, params):
-        if params is not None:
+        if params:
             url += "?%s" % urllib.urlencode(params)
 
         resp, body = self.get(url, self.headers)
diff --git a/tempest/services/compute/xml/floating_ips_client.py b/tempest/services/compute/xml/floating_ips_client.py
index 2f87926..fcb16d3 100644
--- a/tempest/services/compute/xml/floating_ips_client.py
+++ b/tempest/services/compute/xml/floating_ips_client.py
@@ -16,6 +16,7 @@
 #    under the License.
 
 from lxml import etree
+import urllib
 
 from tempest.common.rest_client import RestClientXML
 from tempest import exceptions
@@ -43,11 +44,8 @@
     def list_floating_ips(self, params=None):
         """Returns a list of all floating IPs filtered by any parameters"""
         url = 'os-floating-ips'
-        if params is not None:
-            param_list = []
-            for param, value in params.iteritems():
-                param_list.append("%s=%s" % (param, value))
-            url += "?" + "&".join(param_list)
+        if params:
+            url += '?%s' % urllib.urlencode(params)
 
         resp, body = self.get(url, self.headers)
         body = self._parse_array(etree.fromstring(body))
diff --git a/tempest/services/compute/xml/images_client.py b/tempest/services/compute/xml/images_client.py
index 12ad4d4..b9cb220 100644
--- a/tempest/services/compute/xml/images_client.py
+++ b/tempest/services/compute/xml/images_client.py
@@ -89,8 +89,7 @@
         """Returns a list of all images filtered by any parameters"""
         url = 'images'
         if params:
-            param_list = urllib.urlencode(params)
-            url += "?" + param_list
+            url += '?%s' % urllib.urlencode(params)
 
         resp, body = self.get(url, self.headers)
         body = xml_to_json(etree.fromstring(body))
diff --git a/tempest/services/compute/xml/security_groups_client.py b/tempest/services/compute/xml/security_groups_client.py
index 0e35112..bfd6c7a 100644
--- a/tempest/services/compute/xml/security_groups_client.py
+++ b/tempest/services/compute/xml/security_groups_client.py
@@ -16,6 +16,7 @@
 #    under the License.
 
 from lxml import etree
+import urllib
 
 from tempest.common.rest_client import RestClientXML
 from tempest.services.compute.xml.common import Document
@@ -46,12 +47,8 @@
         """List all security groups for a user"""
 
         url = 'os-security-groups'
-        if params is not None:
-            param_list = []
-            for param, value in params.iteritems():
-                param_list.append("%s=%s" % (param, value))
-
-            url += '?' + ' &'.join(param_list)
+        if params:
+            url += '?%s' % urllib.urlencode(params)
 
         resp, body = self.get(url, self.headers)
         body = self._parse_array(etree.fromstring(body))
diff --git a/tempest/services/compute/xml/servers_client.py b/tempest/services/compute/xml/servers_client.py
index d7c88b7..b354fb9 100644
--- a/tempest/services/compute/xml/servers_client.py
+++ b/tempest/services/compute/xml/servers_client.py
@@ -25,6 +25,7 @@
 from tempest.services.compute.xml.common import xml_to_json
 from tempest.services.compute.xml.common import XMLNS_11
 import time
+import urllib
 
 LOG = logging.getLogger(__name__)
 
@@ -82,24 +83,18 @@
 
     def list_servers(self, params=None):
         url = 'servers/detail'
-        if params is not None:
-            param_list = []
-            for param, value in params.iteritems():
-                param_list.append("%s=%s" % (param, value))
+        if params:
+            url += '?%s' % urllib.urlencode(params)
 
-            url += "?" + "&".join(param_list)
         resp, body = self.get(url, self.headers)
         servers = self._parse_array(etree.fromstring(body))
         return resp, {"servers": servers}
 
     def list_servers_with_detail(self, params=None):
         url = 'servers/detail'
-        if params is not None:
-            param_list = []
-            for param, value in params.iteritems():
-                param_list.append("%s=%s" % (param, value))
+        if params:
+            url += '?%s' % urllib.urlencode(params)
 
-            url += "?" + "&".join(param_list)
         resp, body = self.get(url, self.headers)
         servers = self._parse_array(etree.fromstring(body))
         return resp, {"servers": servers}
diff --git a/tempest/services/compute/xml/volumes_extensions_client.py b/tempest/services/compute/xml/volumes_extensions_client.py
index 0fbc070..871f2e5 100644
--- a/tempest/services/compute/xml/volumes_extensions_client.py
+++ b/tempest/services/compute/xml/volumes_extensions_client.py
@@ -17,6 +17,7 @@
 
 import time
 from lxml import etree
+import urllib
 
 from tempest import exceptions
 from tempest.common.rest_client import RestClientXML
diff --git a/tempest/services/object_storage/account_client.py b/tempest/services/object_storage/account_client.py
index 4eaeb34..0ab5cd4 100644
--- a/tempest/services/object_storage/account_client.py
+++ b/tempest/services/object_storage/account_client.py
@@ -16,6 +16,7 @@
 #    under the License.
 
 import json
+import urllib
 
 from tempest.common.rest_client import RestClient
 
@@ -81,11 +82,9 @@
             DEFAULT:  Python-List returned in response body
         """
 
-        param_list = ['format=%s&' % self.format]
-        if params is not None:
-            for param, value in params.iteritems():
-                param_list.append("%s=%s&" % (param, value))
-        url = '?' + ''.join(param_list)
+        url = '?format=%s' % self.format
+        if params:
+            url += '&%s' + urllib.urlencode(params)
 
         resp, body = self.get(url)
         body = json.loads(body)
diff --git a/tempest/services/object_storage/container_client.py b/tempest/services/object_storage/container_client.py
index bb08de2..37a8375 100644
--- a/tempest/services/object_storage/container_client.py
+++ b/tempest/services/object_storage/container_client.py
@@ -16,6 +16,7 @@
 #    under the License.
 
 import json
+import urllib
 
 from tempest.common.rest_client import RestClient
 
@@ -36,7 +37,7 @@
            Creates a container, with optional metadata passed in as a
            dictonary
         """
-        url = container_name
+        url = str(container_name)
         headers = {}
 
         if metadata is not None:
@@ -48,14 +49,14 @@
 
     def delete_container(self, container_name):
         """Deletes the container (if it's empty)"""
-        url = container_name
+        url = str(container_name)
         resp, body = self.delete(url)
         return resp, body
 
     def update_container_metadata(self, container_name, metadata,
                                   metadata_prefix='X-Container-Meta-'):
         """Updates arbitrary metadata on container"""
-        url = container_name
+        url = str(container_name)
         headers = {}
 
         if metadata is not None:
@@ -68,7 +69,7 @@
     def delete_container_metadata(self, container_name, metadata,
                                   metadata_prefix='X-Remove-Container-Meta-'):
         """Deletes arbitrary metadata on container"""
-        url = container_name
+        url = str(container_name)
         headers = {}
 
         if metadata is not None:
@@ -82,7 +83,7 @@
         """
         Retrieves container metadata headers
         """
-        url = container_name
+        url = str(container_name)
         headers = {"X-Storage-Token": self.token}
         resp, body = self.head(url, headers=headers)
         return resp, body
@@ -162,11 +163,9 @@
         """
 
         url = str(container)
-        param_list = ['format=%s&' % self.format]
-        if params is not None:
-            for param, value in params.iteritems():
-                param_list.append("%s=%s&" % (param, value))
-        url += '?' + ''.join(param_list)
+        url += '?format=%s' % self.format
+        if params:
+            url += '&%s' % urllib.urlencode(params)
 
         resp, body = self.get(url)
         body = json.loads(body)
diff --git a/tempest/services/volume/json/volumes_client.py b/tempest/services/volume/json/volumes_client.py
index 28dae4e..2045f3c 100644
--- a/tempest/services/volume/json/volumes_client.py
+++ b/tempest/services/volume/json/volumes_client.py
@@ -17,6 +17,7 @@
 
 import json
 import time
+import urllib
 
 from tempest.common.rest_client import RestClient
 from tempest import exceptions
@@ -38,12 +39,9 @@
     def list_volumes(self, params=None):
         """List all the volumes created"""
         url = 'volumes'
-        if params is not None:
-            param_list = []
-            for param, value in params.iteritems():
-                param_list.append("%s=%s&" % (param, value))
+        if params:
+                url += '?%s' % urllib.urlencode(params)
 
-            url += '?' + ' '.join(param_list)
         resp, body = self.get(url)
         body = json.loads(body)
         return resp, body['volumes']
@@ -51,12 +49,8 @@
     def list_volumes_with_detail(self, params=None):
         """List the details of all volumes"""
         url = 'volumes/detail'
-        if params is not None:
-            param_list = []
-            for param, value in params.iteritems():
-                param_list.append("%s=%s&" % (param, value))
-
-            url = '?' + ' '.join(param_list)
+        if params:
+                url += '?%s' % urllib.urlencode(params)
 
         resp, body = self.get(url)
         body = json.loads(body)
diff --git a/tempest/services/volume/xml/volumes_client.py b/tempest/services/volume/xml/volumes_client.py
index 9d2f159..b90c65a 100644
--- a/tempest/services/volume/xml/volumes_client.py
+++ b/tempest/services/volume/xml/volumes_client.py
@@ -16,6 +16,7 @@
 #    under the License.
 
 import time
+import urllib
 
 from lxml import etree