Merge "Fix race condition for image test"
diff --git a/doc/source/microversion_testing.rst b/doc/source/microversion_testing.rst
index c1981f9..06062c2 100644
--- a/doc/source/microversion_testing.rst
+++ b/doc/source/microversion_testing.rst
@@ -302,6 +302,10 @@
 
   .. _2.2: https://docs.openstack.org/nova/latest/reference/api-microversion-history.html#id2
 
+  * `2.3`_
+
+  .. _2.3: http://docs.openstack.org/developer/nova/api_microversion_history.html#maximum-in-kilo
+
   * `2.6`_
 
   .. _2.6: https://docs.openstack.org/nova/latest/reference/api-microversion-history.html#id5
diff --git a/tempest/lib/decorators.py b/tempest/lib/decorators.py
index ebe2d61..25ff473 100644
--- a/tempest/lib/decorators.py
+++ b/tempest/lib/decorators.py
@@ -72,19 +72,13 @@
     def decorator(f):
         @functools.wraps(f)
         def wrapper(*func_args, **func_kwargs):
-            skip = False
-            msg = ''
-            if "condition" in kwargs:
-                if kwargs["condition"] is True:
-                    skip = True
-            else:
-                skip = True
-            if "bug" in kwargs and skip is True:
-                bug = kwargs['bug']
+            condition = kwargs.get('condition', True)
+            bug = kwargs.get('bug', None)
+            if bug and condition:
                 bug_type = kwargs.get('bug_type', 'launchpad')
                 bug_url = _get_bug_url(bug, bug_type)
-                msg = "Skipped until bug: %s is resolved." % bug_url
-                raise testtools.TestCase.skipException(msg)
+                raise testtools.TestCase.skipException(
+                    "Skipped until bug: %s is resolved." % bug_url)
             return f(*func_args, **func_kwargs)
         return wrapper
     return decorator
diff --git a/tempest/scenario/manager.py b/tempest/scenario/manager.py
index 8c6b0d0..f725b3f 100644
--- a/tempest/scenario/manager.py
+++ b/tempest/scenario/manager.py
@@ -1510,7 +1510,7 @@
 
         return rules
 
-    def _get_router(self, client=None, project_id=None):
+    def _get_router(self, client=None, project_id=None, **kwargs):
         """Retrieve a router for the given tenant id.
 
         If a public router has been configured, it will be returned.
@@ -1530,11 +1530,20 @@
             body = client.show_router(router_id)
             return body['router']
         elif network_id:
+            name = kwargs.pop('name', None)
+            if not name:
+                namestart = self.__class__.__name__ + '-router'
+                name = data_utils.rand_name(namestart)
+
+            ext_gw_info = kwargs.pop('external_gateway_info', None)
+            if not ext_gw_info:
+                ext_gw_info = dict(network_id=network_id)
             router = client.create_router(
-                name=data_utils.rand_name(self.__class__.__name__ + '-router'),
-                admin_state_up=True,
+                name=name,
+                admin_state_up=kwargs.get('admin_state_up', True),
                 project_id=project_id,
-                external_gateway_info=dict(network_id=network_id))['router']
+                external_gateway_info=ext_gw_info,
+                **kwargs)['router']
             self.addCleanup(test_utils.call_and_ignore_notfound_exc,
                             client.delete_router, router['id'])
             return router
diff --git a/tempest/test.py b/tempest/test.py
index f383bc1..68602d6 100644
--- a/tempest/test.py
+++ b/tempest/test.py
@@ -38,12 +38,6 @@
 
 CONF = config.CONF
 
-# TODO(oomichi): This test.idempotent_id should be removed after all projects
-# switch to use decorators.idempotent_id.
-idempotent_id = debtcollector.moves.moved_function(
-    decorators.idempotent_id, 'idempotent_id', __name__,
-    version='Mitaka', removal_version='?')
-
 
 attr = debtcollector.moves.moved_function(
     decorators.attr, 'attr', __name__,
diff --git a/tempest/tests/test_decorators.py b/tempest/tests/test_decorators.py
index 6018441..1889420 100644
--- a/tempest/tests/test_decorators.py
+++ b/tempest/tests/test_decorators.py
@@ -19,7 +19,6 @@
 from tempest.common import utils
 from tempest import config
 from tempest import exceptions
-from tempest.lib.common.utils import data_utils
 from tempest import test
 from tempest.tests import base
 from tempest.tests import fake_config
@@ -33,47 +32,6 @@
                          fake_config.FakePrivate)
 
 
-# NOTE: The test module is for tempest.test.idempotent_id.
-# After all projects switch to use decorators.idempotent_id,
-# we can remove tempest.test.idempotent_id as well as this
-# test module
-class TestIdempotentIdDecorator(BaseDecoratorsTest):
-
-    def _test_helper(self, _id, **decorator_args):
-        @test.idempotent_id(_id)
-        def foo():
-            """Docstring"""
-            pass
-
-        return foo
-
-    def _test_helper_without_doc(self, _id, **decorator_args):
-        @test.idempotent_id(_id)
-        def foo():
-            pass
-
-        return foo
-
-    def test_positive(self):
-        _id = data_utils.rand_uuid()
-        foo = self._test_helper(_id)
-        self.assertIn('id-%s' % _id, getattr(foo, '__testtools_attrs'))
-        self.assertTrue(foo.__doc__.startswith('Test idempotent id: %s' % _id))
-
-    def test_positive_without_doc(self):
-        _id = data_utils.rand_uuid()
-        foo = self._test_helper_without_doc(_id)
-        self.assertTrue(foo.__doc__.startswith('Test idempotent id: %s' % _id))
-
-    def test_idempotent_id_not_str(self):
-        _id = 42
-        self.assertRaises(TypeError, self._test_helper, _id)
-
-    def test_idempotent_id_not_valid_uuid(self):
-        _id = '42'
-        self.assertRaises(ValueError, self._test_helper, _id)
-
-
 class TestServicesDecorator(BaseDecoratorsTest):
     def _test_services_helper(self, *decorator_args):
         class TestFoo(test.BaseTestCase):
diff --git a/tox.ini b/tox.ini
index c01852b..2315163 100644
--- a/tox.ini
+++ b/tox.ini
@@ -136,7 +136,7 @@
 commands =
     find . -type f -name "*.pyc" -delete
     tempest run --regex '(?!.*\[.*\bslow\b.*\])(^tempest\.api)' --exclude-list ./tools/tempest-integrated-gate-networking-exclude-list.txt {posargs}
-    tempest run --combine --serial --regex '(?!.*\[.*\bslow\b.*\])(^tempest\.scenario)' --exlude-list ./tools/tempest-integrated-gate-networking-exclude-list.txt {posargs}
+    tempest run --combine --serial --regex '(?!.*\[.*\bslow\b.*\])(^tempest\.scenario)' --exclude-list ./tools/tempest-integrated-gate-networking-exclude-list.txt {posargs}
 
 [testenv:integrated-compute]
 envdir = .tox/tempest