Enable a uuid flavor

Current tempest configuration enforces a flavor id should be integer,
but we can create a uuid flavor. For example, the following command
creates a flavor with auto-generated uuid:

  $ nova flavor-create m3.small auto 512 0 1

This patch enables a uuid flavor by changing a flavor_id type from
integer to string.

Change-Id: I6567ef3086710508ef4215e93634601119ce3402
diff --git a/etc/tempest.conf.sample b/etc/tempest.conf.sample
index 251336e..e1edd01 100644
--- a/etc/tempest.conf.sample
+++ b/etc/tempest.conf.sample
@@ -236,10 +236,10 @@
 # value)
 #image_ref_alt={$IMAGE_ID_ALT}
 
-# Valid primary flavor to use in tests. (integer value)
+# Valid primary flavor to use in tests. (string value)
 #flavor_ref=1
 
-# Valid secondary flavor to be used in tests. (integer value)
+# Valid secondary flavor to be used in tests. (string value)
 #flavor_ref_alt=2
 
 # User name used to authenticate to an instance. (string
diff --git a/tempest/api/compute/admin/test_flavors.py b/tempest/api/compute/admin/test_flavors.py
index 8d2fcac..c5a8772 100644
--- a/tempest/api/compute/admin/test_flavors.py
+++ b/tempest/api/compute/admin/test_flavors.py
@@ -15,6 +15,8 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+import uuid
+
 from tempest.api import compute
 from tempest.api.compute import base
 from tempest.common.utils import data_utils
@@ -53,18 +55,16 @@
         self.assertEqual(resp.status, 202)
         self.client.wait_for_resource_deletion(flavor_id)
 
-    @attr(type='gate')
-    def test_create_flavor(self):
+    def _create_flavor(self, flavor_id):
         # Create a flavor and ensure it is listed
         # This operation requires the user to have 'admin' role
         flavor_name = data_utils.rand_name(self.flavor_name_prefix)
-        new_flavor_id = data_utils.rand_int_id(start=1000)
 
         # Create the flavor
         resp, flavor = self.client.create_flavor(flavor_name,
                                                  self.ram, self.vcpus,
                                                  self.disk,
-                                                 new_flavor_id,
+                                                 flavor_id,
                                                  ephemeral=self.ephemeral,
                                                  swap=self.swap,
                                                  rxtx=self.rxtx)
@@ -74,7 +74,6 @@
         self.assertEqual(flavor['vcpus'], self.vcpus)
         self.assertEqual(flavor['disk'], self.disk)
         self.assertEqual(flavor['ram'], self.ram)
-        self.assertEqual(int(flavor['id']), new_flavor_id)
         self.assertEqual(flavor['swap'], self.swap)
         self.assertEqual(flavor['rxtx_factor'], self.rxtx)
         self.assertEqual(flavor['OS-FLV-EXT-DATA:ephemeral'],
@@ -82,10 +81,32 @@
         self.assertEqual(flavor['os-flavor-access:is_public'], True)
 
         # Verify flavor is retrieved
-        resp, flavor = self.client.get_flavor_details(new_flavor_id)
+        resp, flavor = self.client.get_flavor_details(flavor['id'])
         self.assertEqual(resp.status, 200)
         self.assertEqual(flavor['name'], flavor_name)
 
+        return flavor['id']
+
+    @attr(type='gate')
+    def test_create_flavor_with_int_id(self):
+        flavor_id = data_utils.rand_int_id(start=1000)
+        new_flavor_id = self._create_flavor(flavor_id)
+        self.assertEqual(new_flavor_id, str(flavor_id))
+
+    @attr(type='gate')
+    def test_create_flavor_with_uuid_id(self):
+        flavor_id = str(uuid.uuid4())
+        new_flavor_id = self._create_flavor(flavor_id)
+        self.assertEqual(new_flavor_id, flavor_id)
+
+    @attr(type='gate')
+    def test_create_flavor_with_none_id(self):
+        # If nova receives a request with None as flavor_id,
+        # nova generates flavor_id of uuid.
+        flavor_id = None
+        new_flavor_id = self._create_flavor(flavor_id)
+        self.assertEqual(new_flavor_id, str(uuid.UUID(new_flavor_id)))
+
     @attr(type='gate')
     def test_create_flavor_verify_entry_in_list_details(self):
         # Create a flavor and ensure it's details are listed
diff --git a/tempest/api/compute/flavors/test_flavors.py b/tempest/api/compute/flavors/test_flavors.py
index eac98ea..fa99422 100644
--- a/tempest/api/compute/flavors/test_flavors.py
+++ b/tempest/api/compute/flavors/test_flavors.py
@@ -48,7 +48,7 @@
     def test_get_flavor(self):
         # The expected flavor details should be returned
         resp, flavor = self.client.get_flavor_details(self.flavor_ref)
-        self.assertEqual(self.flavor_ref, int(flavor['id']))
+        self.assertEqual(self.flavor_ref, flavor['id'])
 
     @attr(type=['negative', 'gate'])
     def test_get_non_existant_flavor(self):
diff --git a/tempest/api/compute/servers/test_create_server.py b/tempest/api/compute/servers/test_create_server.py
index 44ce405..24ade96 100644
--- a/tempest/api/compute/servers/test_create_server.py
+++ b/tempest/api/compute/servers/test_create_server.py
@@ -72,7 +72,7 @@
                          str(netaddr.IPAddress(self.accessIPv6)))
         self.assertEqual(self.name, self.server['name'])
         self.assertEqual(self.image_ref, self.server['image']['id'])
-        self.assertEqual(str(self.flavor_ref), self.server['flavor']['id'])
+        self.assertEqual(self.flavor_ref, self.server['flavor']['id'])
         self.assertEqual(self.meta, self.server['metadata'])
 
     @attr(type='smoke')
diff --git a/tempest/api/compute/servers/test_server_actions.py b/tempest/api/compute/servers/test_server_actions.py
index 5abde56..e3441bd 100644
--- a/tempest/api/compute/servers/test_server_actions.py
+++ b/tempest/api/compute/servers/test_server_actions.py
@@ -128,7 +128,7 @@
         self.assertEqual(self.server_id, rebuilt_server['id'])
         rebuilt_image_id = rebuilt_server['image']['id']
         self.assertTrue(self.image_ref_alt.endswith(rebuilt_image_id))
-        self.assertEqual(self.flavor_ref, int(rebuilt_server['flavor']['id']))
+        self.assertEqual(self.flavor_ref, rebuilt_server['flavor']['id'])
 
         # Verify the server properties after the rebuild completes
         self.client.wait_for_server_status(rebuilt_server['id'], 'ACTIVE')
@@ -147,8 +147,8 @@
         resp, server = self.client.get_server(self.server_id)
         current_flavor = server['flavor']['id']
         new_flavor_ref = self.flavor_ref_alt \
-            if int(current_flavor) == self.flavor_ref else self.flavor_ref
-        return int(current_flavor), int(new_flavor_ref)
+            if current_flavor == self.flavor_ref else self.flavor_ref
+        return current_flavor, new_flavor_ref
 
     @testtools.skipIf(not resize_available, 'Resize not available.')
     @attr(type='smoke')
@@ -167,7 +167,7 @@
         self.client.wait_for_server_status(self.server_id, 'ACTIVE')
 
         resp, server = self.client.get_server(self.server_id)
-        self.assertEqual(new_flavor_ref, int(server['flavor']['id']))
+        self.assertEqual(new_flavor_ref, server['flavor']['id'])
 
     @testtools.skipIf(not resize_available, 'Resize not available.')
     @attr(type='gate')
@@ -189,7 +189,7 @@
         resp, server = self.client.get_server(self.server_id)
         start = int(time.time())
 
-        while int(server['flavor']['id']) != previous_flavor_ref:
+        while server['flavor']['id'] != previous_flavor_ref:
             time.sleep(self.build_interval)
             resp, server = self.client.get_server(self.server_id)
 
diff --git a/tempest/api/compute/v3/servers/test_server_actions.py b/tempest/api/compute/v3/servers/test_server_actions.py
index 92b9e30..20cdf30 100644
--- a/tempest/api/compute/v3/servers/test_server_actions.py
+++ b/tempest/api/compute/v3/servers/test_server_actions.py
@@ -128,7 +128,7 @@
         self.assertEqual(self.server_id, rebuilt_server['id'])
         rebuilt_image_id = rebuilt_server['image']['id']
         self.assertTrue(self.image_ref_alt.endswith(rebuilt_image_id))
-        self.assertEqual(self.flavor_ref, int(rebuilt_server['flavor']['id']))
+        self.assertEqual(self.flavor_ref, rebuilt_server['flavor']['id'])
 
         # Verify the server properties after the rebuild completes
         self.client.wait_for_server_status(rebuilt_server['id'], 'ACTIVE')
@@ -147,8 +147,8 @@
         resp, server = self.client.get_server(self.server_id)
         current_flavor = server['flavor']['id']
         new_flavor_ref = self.flavor_ref_alt \
-            if int(current_flavor) == self.flavor_ref else self.flavor_ref
-        return int(current_flavor), int(new_flavor_ref)
+            if current_flavor == self.flavor_ref else self.flavor_ref
+        return current_flavor, new_flavor_ref
 
     @testtools.skipIf(not resize_available, 'Resize not available.')
     @attr(type='smoke')
@@ -167,7 +167,7 @@
         self.client.wait_for_server_status(self.server_id, 'ACTIVE')
 
         resp, server = self.client.get_server(self.server_id)
-        self.assertEqual(new_flavor_ref, int(server['flavor']['id']))
+        self.assertEqual(new_flavor_ref, server['flavor']['id'])
 
     @testtools.skipIf(not resize_available, 'Resize not available.')
     @attr(type='gate')
@@ -189,7 +189,7 @@
         resp, server = self.client.get_server(self.server_id)
         start = int(time.time())
 
-        while int(server['flavor']['id']) != previous_flavor_ref:
+        while server['flavor']['id'] != previous_flavor_ref:
             time.sleep(self.build_interval)
             resp, server = self.client.get_server(self.server_id)
 
diff --git a/tempest/config.py b/tempest/config.py
index 6af7d51..823550d 100644
--- a/tempest/config.py
+++ b/tempest/config.py
@@ -117,11 +117,11 @@
     cfg.StrOpt('image_ref_alt',
                default="{$IMAGE_ID_ALT}",
                help="Valid secondary image reference to be used in tests."),
-    cfg.IntOpt('flavor_ref',
-               default=1,
+    cfg.StrOpt('flavor_ref',
+               default="1",
                help="Valid primary flavor to use in tests."),
-    cfg.IntOpt('flavor_ref_alt',
-               default=2,
+    cfg.StrOpt('flavor_ref_alt',
+               default="2",
                help='Valid secondary flavor to be used in tests.'),
     cfg.StrOpt('image_ssh_user',
                default="root",
diff --git a/tempest/services/compute/xml/flavors_client.py b/tempest/services/compute/xml/flavors_client.py
index 363c1a8..a1c74d9 100644
--- a/tempest/services/compute/xml/flavors_client.py
+++ b/tempest/services/compute/xml/flavors_client.py
@@ -43,6 +43,10 @@
     def _format_flavor(self, f):
         flavor = {'links': []}
         for k, v in f.items():
+            if k == 'id':
+                flavor['id'] = v
+                continue
+
             if k == 'link':
                 flavor['links'].append(v)
                 continue