Merge "Use addClassResourceCleanup in test_list_projects"
diff --git a/releasenotes/notes/remove-deprecated-skip_unless_attr-decorator-02bde59a00328f5c.yaml b/releasenotes/notes/remove-deprecated-skip_unless_attr-decorator-02bde59a00328f5c.yaml
new file mode 100644
index 0000000..621731d
--- /dev/null
+++ b/releasenotes/notes/remove-deprecated-skip_unless_attr-decorator-02bde59a00328f5c.yaml
@@ -0,0 +1,4 @@
+---
+upgrade:
+  - |
+    Remove the deprecated decorator ``skip_unless_attr`` in lib/decorators.py.
diff --git a/requirements.txt b/requirements.txt
index 023148b..2300214 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -9,7 +9,7 @@
 netaddr>=0.7.18 # BSD
 testrepository>=0.0.18 # Apache-2.0/BSD
 oslo.concurrency>=3.20.0 # Apache-2.0
-oslo.config>=4.6.0 # Apache-2.0
+oslo.config>=5.1.0 # Apache-2.0
 oslo.log>=3.30.0 # Apache-2.0
 oslo.serialization!=2.19.1,>=2.18.0 # Apache-2.0
 oslo.utils>=3.31.0 # Apache-2.0
diff --git a/tempest/api/compute/servers/test_attach_interfaces.py b/tempest/api/compute/servers/test_attach_interfaces.py
index 3c057ac..0e8f681 100644
--- a/tempest/api/compute/servers/test_attach_interfaces.py
+++ b/tempest/api/compute/servers/test_attach_interfaces.py
@@ -78,8 +78,11 @@
 
         return port
 
-    def _check_interface(self, iface, port_id=None, network_id=None,
-                         fixed_ip=None, mac_addr=None):
+    def _check_interface(self, iface, server_id=None, port_id=None,
+                         network_id=None, fixed_ip=None, mac_addr=None):
+        if server_id:
+            iface = waiters.wait_for_interface_status(
+                self.interfaces_client, server_id, iface['port_id'], 'ACTIVE')
         if port_id:
             self.assertEqual(iface['port_id'], port_id)
         if network_id:
@@ -109,9 +112,8 @@
         network_id = ifs[0]['net_id']
         iface = self.interfaces_client.create_interface(
             server['id'], net_id=network_id)['interfaceAttachment']
-        iface = waiters.wait_for_interface_status(
-            self.interfaces_client, server['id'], iface['port_id'], 'ACTIVE')
-        self._check_interface(iface, network_id=network_id)
+        self._check_interface(iface, server_id=server['id'],
+                              network_id=network_id)
         return iface
 
     def _test_create_interface_by_port_id(self, server, ifs):
@@ -121,9 +123,8 @@
         self.addCleanup(self.ports_client.delete_port, port_id)
         iface = self.interfaces_client.create_interface(
             server['id'], port_id=port_id)['interfaceAttachment']
-        iface = waiters.wait_for_interface_status(
-            self.interfaces_client, server['id'], iface['port_id'], 'ACTIVE')
-        self._check_interface(iface, port_id=port_id, network_id=network_id)
+        self._check_interface(iface, server_id=server['id'], port_id=port_id,
+                              network_id=network_id)
         return iface
 
     def _test_create_interface_by_fixed_ips(self, server, ifs):
@@ -140,9 +141,8 @@
             server['id'], net_id=network_id,
             fixed_ips=fixed_ips)['interfaceAttachment']
         self.addCleanup(self.ports_client.delete_port, iface['port_id'])
-        iface = waiters.wait_for_interface_status(
-            self.interfaces_client, server['id'], iface['port_id'], 'ACTIVE')
-        self._check_interface(iface, fixed_ip=ip_list[0])
+        self._check_interface(iface, server_id=server['id'],
+                              fixed_ip=ip_list[0])
         return iface
 
     def _test_show_interface(self, server, ifs):
@@ -271,7 +271,8 @@
             # attach the port to the server
             iface = self.interfaces_client.create_interface(
                 server['id'], port_id=port_id)['interfaceAttachment']
-            self._check_interface(iface, port_id=port_id)
+            self._check_interface(iface, server_id=server['id'],
+                                  port_id=port_id)
 
             # detach the port from the server; this is a cast in the compute
             # API so we have to poll the port until the device_id is unset.
diff --git a/tempest/lib/decorators.py b/tempest/lib/decorators.py
index acbb7be..e99dd24 100644
--- a/tempest/lib/decorators.py
+++ b/tempest/lib/decorators.py
@@ -15,7 +15,6 @@
 import functools
 import uuid
 
-import debtcollector.removals
 from oslo_log import log as logging
 import six
 import testtools
@@ -87,25 +86,6 @@
     return decorator
 
 
-@debtcollector.removals.remove(removal_version='Queen')
-class skip_unless_attr(object):
-    """Decorator to skip tests if a specified attr does not exists or False"""
-    def __init__(self, attr, msg=None):
-        self.attr = attr
-        self.message = msg or ("Test case attribute %s not found "
-                               "or False") % attr
-
-    def __call__(self, func):
-        @functools.wraps(func)
-        def _skipper(*args, **kw):
-            """Wrapped skipper function."""
-            testobj = args[0]
-            if not getattr(testobj, self.attr, False):
-                raise testtools.TestCase.skipException(self.message)
-            func(*args, **kw)
-        return _skipper
-
-
 def attr(**kwargs):
     """A decorator which applies the testtools attr decorator
 
diff --git a/tempest/tests/lib/test_decorators.py b/tempest/tests/lib/test_decorators.py
index bbebcd3..ed0eea3 100644
--- a/tempest/tests/lib/test_decorators.py
+++ b/tempest/tests/lib/test_decorators.py
@@ -125,35 +125,6 @@
         self.assertRaises(ValueError, self._test_helper, _id)
 
 
-class TestSkipUnlessAttrDecorator(base.TestCase):
-    def _test_skip_unless_attr(self, attr, expected_to_skip=True):
-        class TestFoo(test.BaseTestCase):
-            expected_attr = not expected_to_skip
-
-            @decorators.skip_unless_attr(attr)
-            def test_foo(self):
-                pass
-
-        t = TestFoo('test_foo')
-        if expected_to_skip:
-            self.assertRaises(testtools.TestCase.skipException,
-                              t.test_foo)
-        else:
-            try:
-                t.test_foo()
-            except Exception:
-                raise testtools.TestCase.failureException()
-
-    def test_skip_attr_does_not_exist(self):
-        self._test_skip_unless_attr('unexpected_attr')
-
-    def test_skip_attr_false(self):
-        self._test_skip_unless_attr('expected_attr')
-
-    def test_no_skip_for_attr_exist_and_true(self):
-        self._test_skip_unless_attr('expected_attr', expected_to_skip=False)
-
-
 class TestRelatedBugDecorator(base.TestCase):
     def test_relatedbug_when_no_exception(self):
         f = mock.Mock()