Merge "Update test_networks.py to v2 of Quantum API"
diff --git a/etc/tempest.conf.sample b/etc/tempest.conf.sample
index 02bfdcb..9280c57 100644
--- a/etc/tempest.conf.sample
+++ b/etc/tempest.conf.sample
@@ -178,7 +178,7 @@
 tenant_network_cidr = 10.100.0.0/16
 
 # The mask bits used to partition the tenant block.
-tenant_network_mask_bits = 29
+tenant_network_mask_bits = 28
 
 # If tenant networks are reachable, connectivity checks will be
 # performed directly against addresses on those networks.
diff --git a/setup.py b/setup.py
index 1f071bb..1507797 100755
--- a/setup.py
+++ b/setup.py
@@ -25,7 +25,7 @@
 depend_links = common_setup.parse_dependency_links()
 
 setuptools.setup(name='tempest',
-                 version="2012.2",
+                 version=common_setup.get_version('tempest', "2013.2"),
                  description='Integration test tools',
                  author='OpenStack',
                  author_email='openstack-qa@lists.launchpad.net',
diff --git a/tempest/common/utils/data_utils.py b/tempest/common/utils/data_utils.py
index 82982b8..e75b54f 100644
--- a/tempest/common/utils/data_utils.py
+++ b/tempest/common/utils/data_utils.py
@@ -24,10 +24,10 @@
 
 
 def rand_name(name='test'):
-    return name + str(random.randint(1, 999999))
+    return name + str(random.randint(1, 0x7fffffff))
 
 
-def rand_int_id(start=0, end=999999):
+def rand_int_id(start=0, end=0x7fffffff):
     return random.randint(start, end)
 
 
diff --git a/tempest/services/compute/json/quotas_client.py b/tempest/services/compute/json/quotas_client.py
index 330e80b..37d4131 100644
--- a/tempest/services/compute/json/quotas_client.py
+++ b/tempest/services/compute/json/quotas_client.py
@@ -37,7 +37,7 @@
 
     def update_quota_set(self, tenant_id, injected_file_content_bytes=None,
                          metadata_items=None, ram=None, floating_ips=None,
-                         key_pairs=None, instances=None,
+                         fixed_ips=None, key_pairs=None, instances=None,
                          security_group_rules=None, injected_files=None,
                          cores=None, injected_file_path_bytes=None,
                          security_groups=None):
@@ -59,6 +59,9 @@
         if floating_ips is not None:
             post_body['floating_ips'] = floating_ips
 
+        if fixed_ips is not None:
+            post_body['fixed_ips'] = fixed_ips
+
         if key_pairs is not None:
             post_body['key_pairs'] = key_pairs
 
diff --git a/tempest/services/compute/xml/quotas_client.py b/tempest/services/compute/xml/quotas_client.py
index 0437205..20e04b4 100644
--- a/tempest/services/compute/xml/quotas_client.py
+++ b/tempest/services/compute/xml/quotas_client.py
@@ -57,7 +57,7 @@
 
     def update_quota_set(self, tenant_id, injected_file_content_bytes=None,
                          metadata_items=None, ram=None, floating_ips=None,
-                         key_pairs=None, instances=None,
+                         fixed_ips=None, key_pairs=None, instances=None,
                          security_group_rules=None, injected_files=None,
                          cores=None, injected_file_path_bytes=None,
                          security_groups=None):
@@ -80,6 +80,9 @@
         if floating_ips is not None:
             post_body.add_attr('floating_ips', floating_ips)
 
+        if fixed_ips is not None:
+            post_body.add_attr('fixed_ips', fixed_ips)
+
         if key_pairs is not None:
             post_body.add_attr('key_pairs', key_pairs)
 
diff --git a/tempest/tests/compute/admin/test_quotas.py b/tempest/tests/compute/admin/test_quotas.py
index befcad3..5a9b6f9 100644
--- a/tempest/tests/compute/admin/test_quotas.py
+++ b/tempest/tests/compute/admin/test_quotas.py
@@ -44,7 +44,7 @@
         cls.default_quota_set = {'injected_file_content_bytes': 10240,
                                  'metadata_items': 128, 'injected_files': 5,
                                  'ram': 51200, 'floating_ips': 10,
-                                 'fixed_ips': 10, 'key_pairs': 100,
+                                 'fixed_ips': -1, 'key_pairs': 100,
                                  'injected_file_path_bytes': 255,
                                  'instances': 10, 'security_group_rules': 20,
                                  'cores': 20, 'security_groups': 10}
@@ -60,9 +60,6 @@
 
     @attr(type='smoke')
     def test_get_default_quotas(self):
-        # Tempest two step
-        self.skipTest('Skipped until the Bug 1125468 is resolved')
-
         # Admin can get the default resource quota set for a tenant
         expected_quota_set = self.default_quota_set.copy()
         expected_quota_set['id'] = self.demo_tenant_id
@@ -74,9 +71,6 @@
             self.fail("Admin could not get the default quota set for a tenant")
 
     def test_update_all_quota_resources_for_tenant(self):
-        # Tempest two step
-        self.skipTest('Skipped until the Bug 1125468 is resolved')
-
         # Admin can update all the resource quota limits for a tenant
         new_quota_set = {'injected_file_content_bytes': 20480,
                          'metadata_items': 256, 'injected_files': 10,
@@ -89,6 +83,8 @@
             resp, quota_set = self.adm_client.update_quota_set(
                 self.demo_tenant_id,
                 **new_quota_set)
+            self.addCleanup(self.adm_client.update_quota_set,
+                            self.demo_tenant_id, **self.default_quota_set)
             self.assertEqual(200, resp.status)
             self.assertEqual(new_quota_set, quota_set)
         except Exception:
@@ -103,12 +99,11 @@
 
     #TODO(afazekas): merge these test cases
     def test_get_updated_quotas(self):
-        # Tempest two step
-        self.skipTest('Skipped until the Bug 1125468 is resolved')
-
         # Verify that GET shows the updated quota set
         self.adm_client.update_quota_set(self.demo_tenant_id,
                                          ram='5120')
+        self.addCleanup(self.adm_client.update_quota_set,
+                        self.demo_tenant_id, **self.default_quota_set)
         try:
             resp, quota_set = self.client.get_quota_set(self.demo_tenant_id)
             self.assertEqual(200, resp.status)
diff --git a/tempest/tests/compute/base.py b/tempest/tests/compute/base.py
index 3b2026e..eb30d81 100644
--- a/tempest/tests/compute/base.py
+++ b/tempest/tests/compute/base.py
@@ -96,47 +96,45 @@
         operate in an isolated tenant container.
         """
         admin_client = cls._get_identity_admin_client()
-        rand_name_root = rand_name(cls.__name__)
-        if cls.isolated_creds:
-            # Main user already created. Create the alt one...
-            rand_name_root += '-alt'
-        username = rand_name_root + "-user"
-        email = rand_name_root + "@example.com"
-        tenant_name = rand_name_root + "-tenant"
-        tenant_desc = tenant_name + "-desc"
         password = "pass"
 
-        try:
-            resp, tenant = admin_client.create_tenant(name=tenant_name,
-                                                      description=tenant_desc)
-        except exceptions.Duplicate:
-            if cls.config.compute.allow_tenant_reuse:
-                tenant = admin_client.get_tenant_by_name(tenant_name)
-                LOG.info('Re-using existing tenant %s' % tenant)
-            else:
-                msg = ('Unable to create isolated tenant %s because ' +
-                       'it already exists. If this is related to a ' +
-                       'previous test failure, try using ' +
-                       'allow_tenant_reuse in tempest.conf') % tenant_name
-                raise exceptions.Duplicate(msg)
+        while True:
+            try:
+                rand_name_root = rand_name(cls.__name__)
+                if cls.isolated_creds:
+                # Main user already created. Create the alt one...
+                    rand_name_root += '-alt'
+                tenant_name = rand_name_root + "-tenant"
+                tenant_desc = tenant_name + "-desc"
 
-        try:
-            resp, user = admin_client.create_user(username,
-                                                  password,
-                                                  tenant['id'],
-                                                  email)
-        except exceptions.Duplicate:
-            if cls.config.compute.allow_tenant_reuse:
-                user = admin_client.get_user_by_username(tenant['id'],
-                                                         username)
-                LOG.info('Re-using existing user %s' % user)
-            else:
-                msg = ('Unable to create isolated user %s because ' +
-                       'it already exists. If this is related to a ' +
-                       'previous test failure, try using ' +
-                       'allow_tenant_reuse in tempest.conf') % tenant_name
-                raise exceptions.Duplicate(msg)
+                resp, tenant = admin_client.create_tenant(
+                    name=tenant_name, description=tenant_desc)
+                break
+            except exceptions.Duplicate:
+                if cls.config.compute.allow_tenant_reuse:
+                    tenant = admin_client.get_tenant_by_name(tenant_name)
+                    LOG.info('Re-using existing tenant %s', tenant)
+                    break
 
+        while True:
+            try:
+                rand_name_root = rand_name(cls.__name__)
+                if cls.isolated_creds:
+                # Main user already created. Create the alt one...
+                    rand_name_root += '-alt'
+                username = rand_name_root + "-user"
+                email = rand_name_root + "@example.com"
+                resp, user = admin_client.create_user(username,
+                                                      password,
+                                                      tenant['id'],
+                                                      email)
+                break
+            except exceptions.Duplicate:
+                if cls.config.compute.allow_tenant_reuse:
+                    user = admin_client.get_user_by_username(tenant['id'],
+                                                             username)
+                    LOG.info('Re-using existing user %s', user)
+                    break
         # Store the complete creds (including UUID ids...) for later
         # but return just the username, tenant_name, password tuple
         # that the various clients will use.
diff --git a/tempest/tests/compute/images/test_images_oneserver.py b/tempest/tests/compute/images/test_images_oneserver.py
index 9412d39..ca3dbb5 100644
--- a/tempest/tests/compute/images/test_images_oneserver.py
+++ b/tempest/tests/compute/images/test_images_oneserver.py
@@ -41,7 +41,12 @@
         super(ImagesOneServerTestJSON, cls).setUpClass()
         cls.client = cls.images_client
         cls.servers_client = cls.servers_client
-        resp, cls.server = cls.create_server(wait_until='ACTIVE')
+
+        try:
+            resp, cls.server = cls.create_server(wait_until='ACTIVE')
+        except Exception:
+            cls.tearDownClass()
+            raise
 
         cls.image_ids = []
 
diff --git a/tempest/tests/compute/test_quotas.py b/tempest/tests/compute/test_quotas.py
index 233d639..a84d041 100644
--- a/tempest/tests/compute/test_quotas.py
+++ b/tempest/tests/compute/test_quotas.py
@@ -33,14 +33,11 @@
 
     @attr(type='smoke')
     def test_get_default_quotas(self):
-        # Tempest two step
-        self.skipTest('Skipped until the Bug 1125468 is resolved')
-
         # User can get the default quota set for it's tenant
         expected_quota_set = {'injected_file_content_bytes': 10240,
                               'metadata_items': 128, 'injected_files': 5,
                               'ram': 51200, 'floating_ips': 10,
-                              'fixed_ips': 10, 'key_pairs': 100,
+                              'fixed_ips': -1, 'key_pairs': 100,
                               'injected_file_path_bytes': 255, 'instances': 10,
                               'security_group_rules': 20, 'cores': 20,
                               'id': self.tenant_id, 'security_groups': 10}
diff --git a/tempest/tests/identity/admin/test_users.py b/tempest/tests/identity/admin/test_users.py
index 80c6fc9..0573b21 100644
--- a/tempest/tests/identity/admin/test_users.py
+++ b/tempest/tests/identity/admin/test_users.py
@@ -326,17 +326,9 @@
         invalid_id.append(rand_name("dddd@#%%^$"))
         invalid_id.append('!@#()$%^&*?<>{}[]')
         #List the users with invalid tenant id
-        fail = list()
         for invalid in invalid_id:
-            try:
-                resp, body = self.client.list_users_for_tenant(invalid)
-            except exceptions.NotFound:
-                pass
-            else:
-                fail.append(invalid)
-        if len(fail) != 0:
-            self.fail('Should raise Not Found when list users with invalid'
-                      'tenant ids %s' % fail)
+            self.assertRaises(exceptions.NotFound,
+                              self.client.list_users_for_tenant, invalid)
 
 
 class UsersTestXML(UsersTestJSON):
diff --git a/tempest/tests/network/test_network_quota_basic.py b/tempest/tests/network/test_network_quota_basic.py
new file mode 100644
index 0000000..eaec708
--- /dev/null
+++ b/tempest/tests/network/test_network_quota_basic.py
@@ -0,0 +1,92 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2013 Hewlett-Packard Development Company, L.P.
+# All Rights Reserved.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+from quantumclient.common import exceptions as exc
+from tempest.tests.network.common import TestNetworkSmokeCommon
+
+MAX_REASONABLE_ITERATIONS = 51  # more than enough. Default for port is 50.
+
+
+class TestNetworkQuotaBasic(TestNetworkSmokeCommon):
+    """
+    This test suite contains tests that each loop trying to grab a
+    particular resource until a quota limit is hit.
+    For sanity, there is a maximum number of iterations - if this is hit
+    the test fails. Covers network, subnet, port.
+    """
+
+    @classmethod
+    def check_preconditions(cls):
+        super(TestNetworkQuotaBasic, cls).check_preconditions()
+
+    @classmethod
+    def setUpClass(cls):
+        super(TestNetworkQuotaBasic, cls).setUpClass()
+        cls.check_preconditions()
+        cls.networks = []
+        cls.subnets = []
+        cls.ports = []
+
+    def test_create_network_until_quota_hit(self):
+        hit_limit = False
+        for n in xrange(MAX_REASONABLE_ITERATIONS):
+            try:
+                self.networks.append(
+                    self._create_network(self.tenant_id,
+                                         namestart='network-quotatest-'))
+            except exc.QuantumClientException as e:
+                if (e.status_code != 409):
+                    raise
+                hit_limit = True
+                break
+        self.assertTrue(hit_limit, "Failed: Did not hit quota limit !")
+
+    def test_create_subnet_until_quota_hit(self):
+        if not self.networks:
+            self.networks.append(
+                self._create_network(self.tenant_id,
+                                     namestart='network-quotatest-'))
+        hit_limit = False
+        for n in xrange(MAX_REASONABLE_ITERATIONS):
+            try:
+                self.subnets.append(
+                    self._create_subnet(self.networks[0],
+                                        namestart='subnet-quotatest-'))
+            except exc.QuantumClientException as e:
+                if (e.status_code != 409):
+                    raise
+                hit_limit = True
+                break
+        self.assertTrue(hit_limit, "Failed: Did not hit quota limit !")
+
+    def test_create_ports_until_quota_hit(self):
+        if not self.networks:
+            self.networks.append(
+                self._create_network(self.tenant_id,
+                                     namestart='network-quotatest-'))
+        hit_limit = False
+        for n in xrange(MAX_REASONABLE_ITERATIONS):
+            try:
+                self.ports.append(
+                    self._create_port(self.networks[0],
+                                      namestart='port-quotatest-'))
+            except exc.QuantumClientException as e:
+                if (e.status_code != 409):
+                    raise
+                hit_limit = True
+                break
+        self.assertTrue(hit_limit, "Failed: Did not hit quota limit !")