Minor fixes and docstrings updates

Change-Id: Ibc6c1da236cdfdc1dbb5ad65004247d1696f3ec3
diff --git a/tempest/services/nova/json/flavors_client.py b/tempest/services/nova/json/flavors_client.py
index 84fa9ff..bd77484 100644
--- a/tempest/services/nova/json/flavors_client.py
+++ b/tempest/services/nova/json/flavors_client.py
@@ -39,3 +39,27 @@
         resp, body = self.get("flavors/%s" % str(flavor_id))
         body = json.loads(body)
         return resp, body['flavor']
+
+    def create_flavor(self, name, ram, vcpus, disk, ephemeral, flavor_id,
+                    swap, rxtx):
+        """Creates a new flavor or instance type"""
+        post_body = {
+                'name': name,
+                'ram': ram,
+                'vcpus': vcpus,
+                'disk': disk,
+                'OS-FLV-EXT-DATA:ephemeral': ephemeral,
+                'id': flavor_id,
+                'swap': swap,
+                'rxtx_factor': rxtx
+            }
+
+        post_body = json.dumps({'flavor': post_body})
+        resp, body = self.post('flavors', post_body, self.headers)
+
+        body = json.loads(body)
+        return resp, body['flavor']
+
+    def delete_flavor(self, flavor_id):
+        """Deletes the given flavor"""
+        return self.delete("flavors/%s" % str(flavor_id))
diff --git a/tempest/tests/compute/admin/__init__.py b/tempest/tests/compute/admin/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tempest/tests/compute/admin/__init__.py
diff --git a/tempest/tests/compute/admin/test_flavors.py b/tempest/tests/compute/admin/test_flavors.py
new file mode 100644
index 0000000..377781b
--- /dev/null
+++ b/tempest/tests/compute/admin/test_flavors.py
@@ -0,0 +1,111 @@
+from nose.plugins.attrib import attr
+from nose import SkipTest
+import tempest.config
+from tempest import exceptions
+from tempest import openstack
+from tempest.tests.base_compute_test import BaseComputeTest
+
+
+class FlavorsAdminTest(BaseComputeTest):
+
+    """
+    Tests Flavors API Create and Delete that require admin privileges
+    """
+
+    @classmethod
+    def setUpClass(cls):
+        cls.config = tempest.config.TempestConfig()
+        cls.admin_username = cls.config.compute_admin.username
+        cls.admin_password = cls.config.compute_admin.password
+        cls.admin_tenant = cls.config.compute_admin.tenant_name
+
+        if not(cls.admin_username and cls.admin_password and cls.admin_tenant):
+            raise SkipTest("Missing Admin credentials in configuration")
+        else:
+            cls.admin_os = openstack.AdminManager()
+            cls.admin_client = cls.admin_os.flavors_client
+            cls.flavor_name = 'test_flavor'
+            cls.ram = 512
+            cls.vcpus = 1
+            cls.disk = 10
+            cls.ephemeral = 10
+            cls.new_flavor_id = 1234
+            cls.swap = 1024
+            cls.rxtx = 1
+
+    @attr(type='positive')
+    def test_create_flavor(self):
+        """Create a flavor and ensure it is listed
+        This operation requires the user to have 'admin' role"""
+
+        #Create the flavor
+        resp, flavor = self.admin_client.create_flavor(self.flavor_name,
+                                                        self.ram, self.vcpus,
+                                                        self.disk,
+                                                        self.ephemeral,
+                                                        self.new_flavor_id,
+                                                        self.swap, self.rxtx)
+        self.assertEqual(200, resp.status)
+        self.assertEqual(flavor['name'], self.flavor_name)
+        self.assertEqual(flavor['vcpus'], self.vcpus)
+        self.assertEqual(flavor['disk'], self.disk)
+        self.assertEqual(flavor['ram'], self.ram)
+        self.assertEqual(int(flavor['id']), self.new_flavor_id)
+        self.assertEqual(flavor['swap'], self.swap)
+        self.assertEqual(flavor['rxtx_factor'], self.rxtx)
+        self.assertEqual(flavor['OS-FLV-EXT-DATA:ephemeral'], self.ephemeral)
+
+        #Verify flavor is retrieved
+        resp, flavor = self.admin_client.get_flavor_details(self.new_flavor_id)
+        self.assertEqual(resp.status, 200)
+        self.assertEqual(flavor['name'], self.flavor_name)
+
+        #Delete the flavor
+        resp, body = self.admin_client.delete_flavor(flavor['id'])
+        self.assertEqual(resp.status, 202)
+
+    @attr(type='positive')
+    def test_create_flavor_verify_entry_in_list_details(self):
+        """Create a flavor and ensure it's details are listed
+        This operation requires the user to have 'admin' role"""
+
+        #Create the flavor
+        resp, flavor = self.admin_client.create_flavor(self.flavor_name,
+                                                        self.ram, self.vcpus,
+                                                        self.disk,
+                                                        self.ephemeral,
+                                                        self.new_flavor_id,
+                                                        self.swap, self.rxtx)
+        flag = False
+        #Verify flavor is retrieved
+        resp, flavors = self.admin_client.list_flavors_with_detail()
+        self.assertEqual(resp.status, 200)
+        for flavor in flavors:
+            if flavor['name'] == self.flavor_name:
+                flag = True
+        self.assertTrue(flag)
+
+        #Delete the flavor
+        resp, body = self.admin_client.delete_flavor(self.new_flavor_id)
+        self.assertEqual(resp.status, 202)
+
+    @attr(type='negative')
+    def test_get_flavor_details_for_deleted_flavor(self):
+        """Delete a flavor and ensure it is not listed"""
+
+        # Create a test flavor
+        resp, flavor = self.admin_client.create_flavor(self.flavor_name,
+                                                self.ram,
+                                                self.vcpus, self.disk,
+                                                self.ephemeral,
+                                                self.new_flavor_id,
+                                                self.swap, self.rxtx)
+        self.assertEquals(200, resp.status)
+
+        # Delete the flavor
+        resp, _ = self.admin_client.delete_flavor(self.new_flavor_id)
+        self.assertEqual(resp.status, 202)
+
+        # Get deleted flavor details
+        self.assertRaises(exceptions.NotFound,
+                self.admin_client.get_flavor_details, self.new_flavor_id)
diff --git a/tempest/tests/test_flavors.py b/tempest/tests/test_flavors.py
index 34aa68c..d5d598f 100644
--- a/tempest/tests/test_flavors.py
+++ b/tempest/tests/test_flavors.py
@@ -1,8 +1,5 @@
-import unittest2 as unittest
 from nose.plugins.attrib import attr
 from tempest import exceptions
-from tempest import openstack
-import tempest.config
 from base_compute_test import BaseComputeTest
 
 
@@ -11,13 +8,12 @@
     @classmethod
     def setUpClass(cls):
         cls.client = cls.flavors_client
-        cls.flavor_id = cls.flavor_ref
 
     @attr(type='smoke')
     def test_list_flavors(self):
         """List of all flavors should contain the expected flavor"""
         resp, flavors = self.client.list_flavors()
-        resp, flavor = self.client.get_flavor_details(self.flavor_id)
+        resp, flavor = self.client.get_flavor_details(self.flavor_ref)
         flavor_min_detail = {'id': flavor['id'], 'links': flavor['links'],
                              'name': flavor['name']}
         self.assertTrue(flavor_min_detail in flavors)
@@ -26,14 +22,14 @@
     def test_list_flavors_with_detail(self):
         """Detailed list of all flavors should contain the expected flavor"""
         resp, flavors = self.client.list_flavors_with_detail()
-        resp, flavor = self.client.get_flavor_details(self.flavor_id)
+        resp, flavor = self.client.get_flavor_details(self.flavor_ref)
         self.assertTrue(flavor in flavors)
 
     @attr(type='smoke')
     def test_get_flavor(self):
         """The expected flavor details should be returned"""
-        resp, flavor = self.client.get_flavor_details(self.flavor_id)
-        self.assertEqual(self.flavor_id, str(flavor['id']))
+        resp, flavor = self.client.get_flavor_details(self.flavor_ref)
+        self.assertEqual(self.flavor_ref, str(flavor['id']))
 
     @attr(type='negative')
     def test_get_non_existant_flavor(self):
@@ -120,3 +116,10 @@
         params = {'minRam': flavors[1]['ram']}
         resp, flavors = self.client.list_flavors(params)
         self.assertFalse(any([i for i in flavors if i['id'] == flavor_id]))
+
+    @attr(type='negative')
+    def test_get_flavor_details_for_invalid_flavor_id(self):
+        """Ensure 404 returned for non-existant flavor ID"""
+
+        self.assertRaises(exceptions.NotFound, self.client.get_flavor_details,
+                        9999)