diff -pruN 5.2.1-2/castellan/_config_driver.py 5.4.1-1/castellan/_config_driver.py
--- 5.2.1-2/castellan/_config_driver.py	2025-02-15 06:32:57.000000000 +0000
+++ 5.4.1-1/castellan/_config_driver.py	2025-07-10 14:54:06.000000000 +0000
@@ -123,19 +123,19 @@ class CastellanConfigurationSource(sourc
 
         except KeyError:
             # no mapping 'option = castellan_id'
-            LOG.info("option '[%s] %s' not present in '[%s] mapping_file'",
-                     group_name, option_name, self._name)
+            LOG.debug("option '[%s] %s' not present in '[%s] mapping_file'",
+                      group_name, option_name, self._name)
 
         except KeyManagerError:
             # bad mapping 'option =' without a castellan_id
-            LOG.warning("missing castellan_id for option "
-                        "'[%s] %s' in '[%s] mapping_file'",
-                        group_name, option_name, self._name)
+            LOG.error("missing castellan_id for option '[%s] %s' in '[%s] "
+                      "mapping_file'",
+                      group_name, option_name, self._name)
 
         except ManagedObjectNotFoundError:
             # good mapping, but unknown castellan_id by secret manager
-            LOG.warning("invalid castellan_id for option "
-                        "'[%s] %s' in '[%s] mapping_file'",
-                        group_name, option_name, self._name)
+            LOG.error("invalid castellan_id for option '[%s] %s' in '[%s] "
+                      "mapping_file'",
+                      group_name, option_name, self._name)
 
         return (sources._NoValue, None)
diff -pruN 5.2.1-2/castellan/key_manager/barbican_key_manager.py 5.4.1-1/castellan/key_manager/barbican_key_manager.py
--- 5.2.1-2/castellan/key_manager/barbican_key_manager.py	2025-02-15 06:32:57.000000000 +0000
+++ 5.4.1-1/castellan/key_manager/barbican_key_manager.py	2025-07-10 14:54:06.000000000 +0000
@@ -106,8 +106,6 @@ class BarbicanKeyManager(key_manager.Key
     """Key Manager Interface that wraps the Barbican client API."""
 
     def __init__(self, configuration):
-        self._barbican_client = None
-        self._base_url = None
         self.conf = configuration
         self.conf.register_opts(_barbican_opts, group=_BARBICAN_OPT_GROUP)
         loading.register_session_conf_options(self.conf, _BARBICAN_OPT_GROUP)
@@ -116,12 +114,15 @@ class BarbicanKeyManager(key_manager.Key
                                               _BARBICAN_SERVICE_USER_OPT_GROUP)
         loading.register_auth_conf_options(self.conf,
                                            _BARBICAN_SERVICE_USER_OPT_GROUP)
+        verify_ssl = self.conf.barbican.verify_ssl
+        verify_ssl_path = self.conf.barbican.verify_ssl_path
+        self._verify = verify_ssl and (verify_ssl_path or verify_ssl)
 
     def _get_barbican_client(self, context):
         """Creates a client to connect to the Barbican service.
 
         :param context: the user context for authentication
-        :return: a Barbican Client object
+        :return: tuple of a Barbican Client object and its endpoint
         :raises Forbidden: if the context is None
         :raises KeyManagerError: if context is missing tenant or tenant is
                                  None or error occurs while creating client
@@ -133,21 +134,18 @@ class BarbicanKeyManager(key_manager.Key
             LOG.error(msg)
             raise exception.Forbidden(msg)
 
-        if self._barbican_client and self._current_context == context:
-            return self._barbican_client
-
         try:
             auth = self._get_keystone_auth(context)
-            verify_ssl = self.conf.barbican.verify_ssl
-            verify_ssl_path = self.conf.barbican.verify_ssl_path
-            verify = verify_ssl and verify_ssl_path or verify_ssl
-            sess = session.Session(auth=auth, verify=verify)
-
-            self._barbican_endpoint = self._get_barbican_endpoint(auth, sess)
-            self._barbican_client = barbican_client_import.Client(
-                session=sess,
-                endpoint=self._barbican_endpoint)
-            self._current_context = context
+            sess = session.Session(auth=auth, verify=self._verify)
+
+            endpoint = self._get_barbican_endpoint(auth, sess)
+            return (
+                barbican_client_import.Client(
+                    version=self.conf.barbican.barbican_api_version,
+                    session=sess,
+                    endpoint=endpoint),
+                self._create_base_url(auth, sess, endpoint)
+            )
 
         # TODO(pbourke): more fine grained exception handling - we are eating
         # tracebacks here
@@ -155,11 +153,6 @@ class BarbicanKeyManager(key_manager.Key
             LOG.error("Error creating Barbican client: %s", e)
             raise exception.KeyManagerError(reason=e)
 
-        self._base_url = self._create_base_url(auth,
-                                               sess,
-                                               self._barbican_endpoint)
-        return self._barbican_client
-
     def _get_keystone_auth(self, context):
         if context.__class__.__name__ == 'KeystonePassword':
             auth = identity.Password(
@@ -258,8 +251,7 @@ class BarbicanKeyManager(key_manager.Key
         if endpoint[-1] != '/':
             endpoint += '/'
 
-        base_url = urllib.parse.urljoin(
-            endpoint, api_version)
+        base_url = urllib.parse.urljoin(endpoint, api_version)
 
         return base_url
 
@@ -276,7 +268,7 @@ class BarbicanKeyManager(key_manager.Key
         :return: the UUID of the new key
         :raises KeyManagerError: if key creation fails
         """
-        barbican_client = self._get_barbican_client(context)
+        barbican_client, _ = self._get_barbican_client(context)
 
         try:
             key_order = barbican_client.orders.create_key(
@@ -307,7 +299,7 @@ class BarbicanKeyManager(key_manager.Key
         :raises NotImplementedError: until implemented
         :raises KeyManagerError: if key pair creation fails
         """
-        barbican_client = self._get_barbican_client(context)
+        barbican_client, _ = self._get_barbican_client(context)
 
         try:
             key_pair_order = barbican_client.orders.create_asymmetric(
@@ -396,7 +388,7 @@ class BarbicanKeyManager(key_manager.Key
         :returns: the UUID of the stored object
         :raises KeyManagerError: if object store fails
         """
-        barbican_client = self._get_barbican_client(context)
+        barbican_client, _ = self._get_barbican_client(context)
 
         try:
             secret = self._get_barbican_object(barbican_client,
@@ -410,16 +402,16 @@ class BarbicanKeyManager(key_manager.Key
             LOG.error("Error storing object: %s", e)
             raise exception.KeyManagerError(reason=e)
 
-    def _create_secret_ref(self, object_id):
+    def _create_secret_ref(self, base_url, object_id):
         """Creates the URL required for accessing a secret.
 
+        :param endpoint: Base endpoint URL
         :param object_id: the UUID of the key to copy
         :return: the URL of the requested secret
         """
         if not object_id:
             msg = _("Key ID is None")
             raise exception.KeyManagerError(reason=msg)
-        base_url = self._base_url
         if base_url[-1] != '/':
             base_url += '/'
         return urllib.parse.urljoin(base_url, "secrets/" + object_id)
@@ -578,10 +570,10 @@ class BarbicanKeyManager(key_manager.Key
         :raises HTTPServerError: if object retrieval fails with 5xx
         """
 
-        barbican_client = self._get_barbican_client(context)
+        barbican_client, base_url = self._get_barbican_client(context)
 
         try:
-            secret_ref = self._create_secret_ref(object_id)
+            secret_ref = self._create_secret_ref(base_url, object_id)
             return barbican_client.secrets.get(secret_ref)
         except (barbican_exceptions.HTTPAuthError,
                 barbican_exceptions.HTTPClientError,
@@ -633,9 +625,9 @@ class BarbicanKeyManager(key_manager.Key
         :raises KeyManagerError: if object deletion fails
         :raises ManagedObjectNotFoundError: if the object could not be found
         """
-        barbican_client = self._get_barbican_client(context)
+        barbican_client, base_url = self._get_barbican_client(context)
         try:
-            secret_ref = self._create_secret_ref(managed_object_id)
+            secret_ref = self._create_secret_ref(base_url, managed_object_id)
             barbican_client.secrets.delete(secret_ref, force)
         except (barbican_exceptions.HTTPAuthError,
                 barbican_exceptions.HTTPClientError,
@@ -658,9 +650,9 @@ class BarbicanKeyManager(key_manager.Key
         :raises ManagedObjectNotFoundError: if the object could not be found
         """
 
-        barbican_client = self._get_barbican_client(context)
+        barbican_client, base_url = self._get_barbican_client(context)
         try:
-            secret_ref = self._create_secret_ref(managed_object_id)
+            secret_ref = self._create_secret_ref(base_url, managed_object_id)
             barbican_client.secrets.register_consumer(
                 secret_ref, **consumer_data)
 
@@ -676,9 +668,9 @@ class BarbicanKeyManager(key_manager.Key
 
     def remove_consumer(self, context, managed_object_id, consumer_data):
 
-        barbican_client = self._get_barbican_client(context)
+        barbican_client, base_url = self._get_barbican_client(context)
         try:
-            secret_ref = self._create_secret_ref(managed_object_id)
+            secret_ref = self._create_secret_ref(base_url, managed_object_id)
             barbican_client.secrets.remove_consumer(
                 secret_ref, **consumer_data)
         except (barbican_exceptions.HTTPAuthError,
@@ -703,7 +695,7 @@ class BarbicanKeyManager(key_manager.Key
         :raises KeyManagerError: if listing secrets fails
         """
         objects = []
-        barbican_client = self._get_barbican_client(context)
+        barbican_client, _ = self._get_barbican_client(context)
 
         if object_type and object_type not in self._secret_type_dict:
             msg = _("Invalid secret type: %s") % object_type
diff -pruN 5.2.1-2/castellan/options.py 5.4.1-1/castellan/options.py
--- 5.2.1-2/castellan/options.py	2025-02-15 06:32:57.000000000 +0000
+++ 5.4.1-1/castellan/options.py	2025-07-10 14:54:06.000000000 +0000
@@ -18,15 +18,8 @@ from oslo_config import cfg
 from oslo_log import log
 
 from castellan import key_manager
-try:
-    from castellan.key_manager import barbican_key_manager as bkm
-except ImportError:
-    bkm = None
-
-try:
-    from castellan.key_manager import vault_key_manager as vkm
-except ImportError:
-    vkm = None
+from castellan.key_manager import barbican_key_manager as bkm
+from castellan.key_manager import vault_key_manager as vkm
 
 from castellan.common import utils
 
@@ -86,63 +79,61 @@ def set_defaults(conf, backend=None, bar
     if default_backend is not None:
         conf.set_default('backend', default_backend, group='key_manager')
 
-    if bkm is not None:
-        if barbican_endpoint is not None:
-            conf.set_default('barbican_endpoint', barbican_endpoint,
-                             group=bkm._BARBICAN_OPT_GROUP)
-        if barbican_api_version is not None:
-            conf.set_default('barbican_api_version', barbican_api_version,
-                             group=bkm._BARBICAN_OPT_GROUP)
-        if auth_endpoint is not None:
-            conf.set_default('auth_endpoint', auth_endpoint,
-                             group=bkm._BARBICAN_OPT_GROUP)
-        if retry_delay is not None:
-            conf.set_default('retry_delay', retry_delay,
-                             group=bkm._BARBICAN_OPT_GROUP)
-        if number_of_retries is not None:
-            conf.set_default('number_of_retries', number_of_retries,
-                             group=bkm._BARBICAN_OPT_GROUP)
-        if verify_ssl is not None:
-            conf.set_default('verify_ssl', verify_ssl,
-                             group=bkm._BARBICAN_OPT_GROUP)
-        if verify_ssl_path is not None:
-            conf.set_default('verify_ssl_path', verify_ssl_path,
-                             group=bkm._BARBICAN_OPT_GROUP)
-        if barbican_endpoint_type is not None:
-            conf.set_default('barbican_endpoint_type', barbican_endpoint_type,
-                             group=bkm._BARBICAN_OPT_GROUP)
-
-    if vkm is not None:
-        if vault_root_token_id is not None:
-            conf.set_default('root_token_id', vault_root_token_id,
-                             group=vkm._VAULT_OPT_GROUP)
-        if vault_approle_role_id is not None:
-            conf.set_default('approle_role_id', vault_approle_role_id,
-                             group=vkm._VAULT_OPT_GROUP)
-        if vault_approle_secret_id is not None:
-            conf.set_default('approle_secret_id', vault_approle_secret_id,
-                             group=vkm._VAULT_OPT_GROUP)
-        if vault_kv_mountpoint is not None:
-            conf.set_default('kv_mountpoint', vault_kv_mountpoint,
-                             group=vkm._VAULT_OPT_GROUP)
-        if vault_kv_path is not None:
-            conf.set_default('kv_path', vault_kv_path,
-                             group=vkm._VAULT_OPT_GROUP)
-        if vault_url is not None:
-            conf.set_default('vault_url', vault_url,
-                             group=vkm._VAULT_OPT_GROUP)
-        if vault_ssl_ca_crt_file is not None:
-            conf.set_default('ssl_ca_crt_file', vault_ssl_ca_crt_file,
-                             group=vkm._VAULT_OPT_GROUP)
-        if vault_use_ssl is not None:
-            conf.set_default('use_ssl', vault_use_ssl,
-                             group=vkm._VAULT_OPT_GROUP)
-        if vault_namespace is not None:
-            conf.set_default('namespace', vault_namespace,
-                             group=vkm._VAULT_OPT_GROUP)
-        if vault_kv_version is not None:
-            conf.set_default('kv_version', vault_kv_version,
-                             group=vkm._VAULT_OPT_GROUP)
+    if barbican_endpoint is not None:
+        conf.set_default('barbican_endpoint', barbican_endpoint,
+                         group=bkm._BARBICAN_OPT_GROUP)
+    if barbican_api_version is not None:
+        conf.set_default('barbican_api_version', barbican_api_version,
+                         group=bkm._BARBICAN_OPT_GROUP)
+    if auth_endpoint is not None:
+        conf.set_default('auth_endpoint', auth_endpoint,
+                         group=bkm._BARBICAN_OPT_GROUP)
+    if retry_delay is not None:
+        conf.set_default('retry_delay', retry_delay,
+                         group=bkm._BARBICAN_OPT_GROUP)
+    if number_of_retries is not None:
+        conf.set_default('number_of_retries', number_of_retries,
+                         group=bkm._BARBICAN_OPT_GROUP)
+    if verify_ssl is not None:
+        conf.set_default('verify_ssl', verify_ssl,
+                         group=bkm._BARBICAN_OPT_GROUP)
+    if verify_ssl_path is not None:
+        conf.set_default('verify_ssl_path', verify_ssl_path,
+                         group=bkm._BARBICAN_OPT_GROUP)
+    if barbican_endpoint_type is not None:
+        conf.set_default('barbican_endpoint_type', barbican_endpoint_type,
+                         group=bkm._BARBICAN_OPT_GROUP)
+
+    if vault_root_token_id is not None:
+        conf.set_default('root_token_id', vault_root_token_id,
+                         group=vkm._VAULT_OPT_GROUP)
+    if vault_approle_role_id is not None:
+        conf.set_default('approle_role_id', vault_approle_role_id,
+                         group=vkm._VAULT_OPT_GROUP)
+    if vault_approle_secret_id is not None:
+        conf.set_default('approle_secret_id', vault_approle_secret_id,
+                         group=vkm._VAULT_OPT_GROUP)
+    if vault_kv_mountpoint is not None:
+        conf.set_default('kv_mountpoint', vault_kv_mountpoint,
+                         group=vkm._VAULT_OPT_GROUP)
+    if vault_kv_path is not None:
+        conf.set_default('kv_path', vault_kv_path,
+                         group=vkm._VAULT_OPT_GROUP)
+    if vault_url is not None:
+        conf.set_default('vault_url', vault_url,
+                         group=vkm._VAULT_OPT_GROUP)
+    if vault_ssl_ca_crt_file is not None:
+        conf.set_default('ssl_ca_crt_file', vault_ssl_ca_crt_file,
+                         group=vkm._VAULT_OPT_GROUP)
+    if vault_use_ssl is not None:
+        conf.set_default('use_ssl', vault_use_ssl,
+                         group=vkm._VAULT_OPT_GROUP)
+    if vault_namespace is not None:
+        conf.set_default('namespace', vault_namespace,
+                         group=vkm._VAULT_OPT_GROUP)
+    if vault_kv_version is not None:
+        conf.set_default('kv_version', vault_kv_version,
+                         group=vkm._VAULT_OPT_GROUP)
 
 
 def enable_logging(conf=None, app_name='castellan'):
diff -pruN 5.2.1-2/castellan/tests/unit/key_manager/test_barbican_key_manager.py 5.4.1-1/castellan/tests/unit/key_manager/test_barbican_key_manager.py
--- 5.2.1-2/castellan/tests/unit/key_manager/test_barbican_key_manager.py	2025-02-15 06:32:57.000000000 +0000
+++ 5.4.1-1/castellan/tests/unit/key_manager/test_barbican_key_manager.py	2025-07-10 14:54:06.000000000 +0000
@@ -18,6 +18,7 @@ Test cases for the barbican key manager.
 """
 import calendar
 from unittest import mock
+import uuid
 
 from barbicanclient import exceptions as barbican_exceptions
 from keystoneauth1 import identity
@@ -44,10 +45,9 @@ class BarbicanKeyManagerTestCase(test_ke
         self.ctxt = mock.Mock(spec=context.RequestContext)
         self.ctxt.auth_token = "fake_token"
         self.ctxt.project_name = "foo"
+        self.ctxt.project_id = str(uuid.uuid4()).replace('-', '')
         self.ctxt.project_domain_name = "foo"
-
-        # Create mock barbican client
-        self._build_mock_barbican()
+        self.ctxt.project_domain_id = str(uuid.uuid4()).replace('-', '')
 
         # Create a key_id, secret_ref, pre_hex, and hex to use
         self.key_id = "d152fa13-2b41-42ca-a934-6c21566c0f40"
@@ -55,38 +55,11 @@ class BarbicanKeyManagerTestCase(test_ke
         self.pre_hex = "AIDxQp2++uAbKaTVDMXFYIu8PIugJGqkK0JLqkU0rhY="
         self.hex = ("0080f1429dbefae01b29a4d50cc5c5608bbc3c8ba0246aa42b424baa4"
                     "534ae16")
-        self.key_mgr._base_url = "http://host:9311/v1/"
+        self.base_url = "http://host:9311/v1/"
 
         self.key_mgr.conf.barbican.number_of_retries = 3
         self.key_mgr.conf.barbican.retry_delay = 1
 
-        self.addCleanup(self._restore)
-
-    def _restore(self):
-        try:
-            getattr(self, 'original_key')
-            sym_key.SymmetricKey = self.original_key
-        except AttributeError:
-            return None
-
-    def _build_mock_barbican(self):
-        self.mock_barbican = mock.MagicMock(name='mock_barbican')
-
-        # Set commonly used methods
-        self.get = self.mock_barbican.secrets.get
-        self.delete = self.mock_barbican.secrets.delete
-        self.store = self.mock_barbican.secrets.store
-        self.create = self.mock_barbican.secrets.create
-        self.list = self.mock_barbican.secrets.list
-
-        self.add_consumer = self.mock_barbican.secrets.add_consumer
-        self.remove_consumer = self.mock_barbican.secrets.remove_consumer
-        self.list_versions = self.mock_barbican.versions.list_versions
-
-        self.key_mgr._barbican_client = self.mock_barbican
-        self.key_mgr._current_context = self.ctxt
-        self.key_mgr._version_client = self.mock_barbican
-
     def test_barbican_endpoint(self):
         endpoint_data = mock.Mock()
         endpoint_data.url = 'http://localhost:9311'
@@ -242,7 +215,6 @@ class BarbicanKeyManagerTestCase(test_ke
 
         endpoint_data = mock.Mock()
         endpoint_data.api_version = 'v321'
-
         auth = mock.Mock(spec=['service_catalog'])
         auth.service_catalog.endpoint_data_for.return_value = endpoint_data
 
@@ -288,47 +260,61 @@ class BarbicanKeyManagerTestCase(test_ke
         auth.get_discovery.assert_called_once_with(sess, url=endpoint)
         self.assertEqual(1, discovery.raw_version_data.call_count)
 
-    def test_create_key(self):
+    @mock.patch('castellan.key_manager.barbican_key_manager.'
+                'BarbicanKeyManager._get_barbican_client')
+    def test_create_key(self, mock_get_client):
+        mock_client = mock.Mock()
+        mock_get_client.return_value = (mock_client, self.base_url)
+
         # Create order_ref_url and assign return value
         order_ref_url = ("http://localhost:9311/v1/orders/"
                          "4fe939b7-72bc-49aa-bd1e-e979589858af")
         key_order = mock.Mock()
-        self.mock_barbican.orders.create_key.return_value = key_order
+        mock_client.orders.create_key.return_value = key_order
         key_order.submit.return_value = order_ref_url
 
         # Create order and assign return value
         order = mock.Mock()
         order.secret_ref = self.secret_ref
         order.status = 'ACTIVE'
-        self.mock_barbican.orders.get.return_value = order
+        mock_client.orders.get.return_value = order
 
         # Create the key, get the UUID
         returned_uuid = self.key_mgr.create_key(self.ctxt,
                                                 algorithm='AES',
                                                 length=256)
 
-        self.mock_barbican.orders.get.assert_called_once_with(order_ref_url)
+        mock_client.orders.get.assert_called_once_with(order_ref_url)
         self.assertEqual(self.key_id, returned_uuid)
 
     def test_create_key_null_context(self):
-        self.key_mgr._barbican_client = None
         self.assertRaises(exception.Forbidden,
                           self.key_mgr.create_key, None, 'AES', 256)
 
-    def test_create_key_with_error(self):
+    @mock.patch('castellan.key_manager.barbican_key_manager.'
+                'BarbicanKeyManager._get_barbican_client')
+    def test_create_key_with_error(self, mock_get_client):
+        mock_client = mock.Mock()
+        mock_get_client.return_value = (mock_client, self.base_url)
+
         key_order = mock.Mock()
-        self.mock_barbican.orders.create_key.return_value = key_order
+        mock_client.orders.create_key.return_value = key_order
         key_order.submit = mock.Mock(
             side_effect=barbican_exceptions.HTTPClientError('test error'))
         self.assertRaises(exception.KeyManagerError,
                           self.key_mgr.create_key, self.ctxt, 'AES', 256)
 
-    def test_create_key_pair(self):
+    @mock.patch('castellan.key_manager.barbican_key_manager.'
+                'BarbicanKeyManager._get_barbican_client')
+    def test_create_key_pair(self, mock_get_client):
+        mock_client = mock.Mock()
+        mock_get_client.return_value = (mock_client, self.base_url)
+
         # Create order_ref_url and assign return value
         order_ref_url = ("http://localhost:9311/v1/orders/"
                          "f45bf211-a917-4ead-9aec-1c91e52609df")
         asym_order = mock.Mock()
-        self.mock_barbican.orders.create_asymmetric.return_value = asym_order
+        mock_client.orders.create_asymmetric.return_value = asym_order
         asym_order.submit.return_value = order_ref_url
 
         # Create order and assign return value
@@ -337,7 +323,7 @@ class BarbicanKeyManagerTestCase(test_ke
         container_ref = ("http://localhost:9311/v1/containers/" + container_id)
         order.container_ref = container_ref
         order.status = 'ACTIVE'
-        self.mock_barbican.orders.get.return_value = order
+        mock_client.orders.get.return_value = order
 
         # Create container and assign return value
         container = mock.Mock()
@@ -347,7 +333,7 @@ class BarbicanKeyManagerTestCase(test_ke
         priv_key_ref = ("http://localhost:9311/v1/secrets/" + private_key_id)
         container.secret_refs = {'public_key': pub_key_ref,
                                  'private_key': priv_key_ref}
-        self.mock_barbican.containers.get.return_value = container
+        mock_client.containers.get.return_value = container
 
         # Create the keys, get the UUIDs
         returned_private_uuid, returned_public_uuid = (
@@ -355,70 +341,107 @@ class BarbicanKeyManagerTestCase(test_ke
                                          algorithm='RSA',
                                          length=2048))
 
-        self.mock_barbican.orders.get.assert_called_once_with(order_ref_url)
-        self.mock_barbican.containers.get.assert_called_once_with(
+        mock_client.orders.get.assert_called_once_with(order_ref_url)
+        mock_client.containers.get.assert_called_once_with(
             container_ref)
 
-        self.mock_barbican.orders.get.assert_called_once_with(order_ref_url)
+        mock_client.orders.get.assert_called_once_with(order_ref_url)
         self.assertEqual(private_key_id, returned_private_uuid)
         self.assertEqual(public_key_id, returned_public_uuid)
 
     def test_create_key_pair_null_context(self):
-        self.key_mgr._barbican_client = None
         self.assertRaises(exception.Forbidden,
                           self.key_mgr.create_key_pair, None, 'RSA', 2048)
 
-    def test_create_key_pair_with_error(self):
+    @mock.patch('castellan.key_manager.barbican_key_manager.'
+                'BarbicanKeyManager._get_barbican_client')
+    def test_create_key_pair_with_error(self, mock_get_client):
+        mock_client = mock.Mock()
+        mock_get_client.return_value = (mock_client, self.base_url)
+
         asym_order = mock.Mock()
-        self.mock_barbican.orders.create_asymmetric.return_value = asym_order
+        mock_client.orders.create_asymmetric.return_value = asym_order
         asym_order.submit = mock.Mock(
             side_effect=barbican_exceptions.HTTPClientError('test error'))
         self.assertRaises(exception.KeyManagerError,
                           self.key_mgr.create_key_pair, self.ctxt, 'RSA', 2048)
 
     def test_delete_null_context(self):
-        self.key_mgr._barbican_client = None
         self.assertRaises(exception.Forbidden,
                           self.key_mgr.delete, None, self.key_id)
 
-    def test_delete_key(self):
+    @mock.patch('castellan.key_manager.barbican_key_manager.'
+                'BarbicanKeyManager._get_barbican_client')
+    def test_delete_key(self, mock_get_client):
+        mock_client = mock.Mock()
+        mock_get_client.return_value = (mock_client, self.base_url)
+
         self.key_mgr.delete(self.ctxt, self.key_id)
-        self.delete.assert_called_once_with(self.secret_ref, False)
+        mock_client.secrets.delete.assert_called_once_with(
+            self.secret_ref, False)
+
+    @mock.patch('castellan.key_manager.barbican_key_manager.'
+                'BarbicanKeyManager._get_barbican_client')
+    def test_delete_secret_with_consumers_no_force_parameter(
+            self, mock_get_client):
+        mock_client = mock.Mock()
+        mock_get_client.return_value = (mock_client, self.base_url)
 
-    def test_delete_secret_with_consumers_no_force_parameter(self):
-        self.mock_barbican.secrets.delete = mock.Mock(
+        mock_client.secrets.delete = mock.Mock(
             side_effect=exception.KeyManagerError(
                 "Secret has consumers! Use the 'force' parameter."))
         self.assertRaises(exception.KeyManagerError,
                           self.key_mgr.delete, self.ctxt, self.key_id)
-        self.mock_barbican.secrets.delete.assert_called_once_with(
+        mock_client.secrets.delete.assert_called_once_with(
             self.secret_ref, False)
 
-    def test_delete_secret_with_consumers_force_parameter_false(self):
-        self.mock_barbican.secrets.delete = mock.Mock(
-            side_effect=barbican_exceptions.HTTPClientError(
-                "Secret has consumers! Use the 'force' parameter."))
+    @mock.patch('castellan.key_manager.barbican_key_manager.'
+                'BarbicanKeyManager._get_barbican_client')
+    def test_delete_secret_with_consumers_force_parameter_false(
+            self, mock_get_client):
+        mock_client = mock.Mock()
+        mock_get_client.return_value = (mock_client, self.base_url)
+
+        mock_client.secrets.delete.side_effect = \
+            barbican_exceptions.HTTPClientError(
+                "Secret has consumers! Use the 'force' parameter.")
         self.assertRaises(exception.KeyManagerError,
                           self.key_mgr.delete, self.ctxt, self.key_id,
                           force=False)
-        self.mock_barbican.secrets.delete.assert_called_once_with(
+        mock_client.secrets.delete.assert_called_once_with(
             self.secret_ref, False)
 
-    def test_delete_secret_with_consumers_force_parameter_true(self):
+    @mock.patch('castellan.key_manager.barbican_key_manager.'
+                'BarbicanKeyManager._get_barbican_client')
+    def test_delete_secret_with_consumers_force_parameter_true(
+            self, mock_get_client):
+        mock_client = mock.Mock()
+        mock_get_client.return_value = (mock_client, self.base_url)
+
         self.key_mgr.delete(self.ctxt, self.key_id, force=True)
-        self.delete.assert_called_once_with(self.secret_ref, True)
+        mock_client.secrets.delete.assert_called_once_with(
+            self.secret_ref, True)
 
     def test_delete_unknown_key(self):
         self.assertRaises(exception.KeyManagerError,
                           self.key_mgr.delete, self.ctxt, None)
 
-    def test_delete_with_error(self):
-        self.mock_barbican.secrets.delete = mock.Mock(
+    @mock.patch('castellan.key_manager.barbican_key_manager.'
+                'BarbicanKeyManager._get_barbican_client')
+    def test_delete_with_error(self, mock_get_client):
+        mock_client = mock.Mock()
+        mock_get_client.return_value = (mock_client, self.base_url)
+        mock_client.secrets.delete = mock.Mock(
             side_effect=barbican_exceptions.HTTPClientError('test error'))
         self.assertRaises(exception.KeyManagerError,
                           self.key_mgr.delete, self.ctxt, self.key_id)
 
-    def test_get_key(self):
+    @mock.patch('castellan.key_manager.barbican_key_manager.'
+                'BarbicanKeyManager._get_barbican_client')
+    def test_get_key(self, mock_get_client):
+        mock_client = mock.Mock()
+        mock_get_client.return_value = (mock_client, self.base_url)
+
         original_secret_metadata = mock.Mock()
         original_secret_metadata.algorithm = mock.sentinel.alg
         original_secret_metadata.bit_length = mock.sentinel.bit
@@ -439,17 +462,16 @@ class BarbicanKeyManagerTestCase(test_ke
         original_secret_data = b'test key'
         original_secret_metadata.payload = original_secret_data
 
-        self.mock_barbican.secrets.get.return_value = original_secret_metadata
+        mock_client.secrets.get.return_value = original_secret_metadata
         key = self.key_mgr.get(self.ctxt, self.key_id)
 
-        self.get.assert_called_once_with(self.secret_ref)
+        mock_client.secrets.get.assert_called_once_with(self.secret_ref)
         self.assertEqual(key_id, key.id)
         self.assertEqual(key_name, key.name)
         self.assertEqual(original_secret_data, key.get_encoded())
         self.assertEqual(created_posix, key.created)
 
     def test_get_null_context(self):
-        self.key_mgr._barbican_client = None
         self.assertRaises(exception.Forbidden,
                           self.key_mgr.get, None, self.key_id)
 
@@ -457,13 +479,22 @@ class BarbicanKeyManagerTestCase(test_ke
         self.assertRaises(exception.KeyManagerError,
                           self.key_mgr.get, self.ctxt, None)
 
-    def test_get_with_error(self):
-        self.mock_barbican.secrets.get = mock.Mock(
-            side_effect=barbican_exceptions.HTTPClientError('test error'))
+    @mock.patch('castellan.key_manager.barbican_key_manager.'
+                'BarbicanKeyManager._get_barbican_client')
+    def test_get_with_error(self, mock_get_client):
+        mock_client = mock.Mock()
+        mock_get_client.return_value = (mock_client, self.base_url)
+        mock_client.secrets.get.side_effect = \
+            barbican_exceptions.HTTPClientError('test error')
         self.assertRaises(exception.KeyManagerError,
                           self.key_mgr.get, self.ctxt, self.key_id)
 
-    def test_store_key(self):
+    @mock.patch('castellan.key_manager.barbican_key_manager.'
+                'BarbicanKeyManager._get_barbican_client')
+    def test_store_key(self, mock_get_client):
+        mock_client = mock.Mock()
+        mock_get_client.return_value = (mock_client, self.base_url)
+
         # Create Key to store
         secret_key = bytes(b'\x01\x02\xA0\xB3')
         key_length = len(secret_key) * 8
@@ -473,20 +504,26 @@ class BarbicanKeyManagerTestCase(test_ke
 
         # Define the return values
         secret = mock.Mock()
-        self.create.return_value = secret
+        mock_client.secrets.create.return_value = secret
         secret.store.return_value = self.secret_ref
 
         # Store the Key
         returned_uuid = self.key_mgr.store(self.ctxt, _key)
 
-        self.create.assert_called_once_with(algorithm='AES',
-                                            bit_length=key_length,
-                                            name=None,
-                                            payload=secret_key,
-                                            secret_type='symmetric')
+        mock_client.secrets.create.assert_called_once_with(
+            algorithm='AES',
+            bit_length=key_length,
+            name=None,
+            payload=secret_key,
+            secret_type='symmetric')
         self.assertEqual(self.key_id, returned_uuid)
 
-    def test_store_key_with_name(self):
+    @mock.patch('castellan.key_manager.barbican_key_manager.'
+                'BarbicanKeyManager._get_barbican_client')
+    def test_store_key_with_name(self, mock_get_client):
+        mock_client = mock.Mock()
+        mock_get_client.return_value = (mock_client, self.base_url)
+
         # Create Key to store
         secret_key = bytes(b'\x01\x02\xA0\xB3')
         key_length = len(secret_key) * 8
@@ -498,27 +535,31 @@ class BarbicanKeyManagerTestCase(test_ke
 
         # Define the return values
         secret = mock.Mock()
-        self.create.return_value = secret
+        mock_client.secrets.create.return_value = secret
         secret.store.return_value = self.secret_ref
 
         # Store the Key
         returned_uuid = self.key_mgr.store(self.ctxt, _key)
 
-        self.create.assert_called_once_with(algorithm='AES',
-                                            bit_length=key_length,
-                                            payload=secret_key,
-                                            name=secret_name,
-                                            secret_type='symmetric')
+        mock_client.secrets.create.assert_called_once_with(
+            algorithm='AES',
+            bit_length=key_length,
+            payload=secret_key,
+            name=secret_name,
+            secret_type='symmetric')
         self.assertEqual(self.key_id, returned_uuid)
 
     def test_store_null_context(self):
-        self.key_mgr._barbican_client = None
         self.assertRaises(exception.Forbidden,
                           self.key_mgr.store, None, None)
 
-    def test_store_with_error(self):
-        self.mock_barbican.secrets.create = mock.Mock(
-            side_effect=barbican_exceptions.HTTPClientError('test error'))
+    @mock.patch('castellan.key_manager.barbican_key_manager.'
+                'BarbicanKeyManager._get_barbican_client')
+    def test_store_with_error(self, mock_get_client):
+        mock_client = mock.Mock()
+        mock_get_client.return_value = (mock_client, self.base_url)
+        mock_client.secrets.create.side_effect = \
+            barbican_exceptions.HTTPClientError('test error')
         secret_key = bytes(b'\x01\x02\xA0\xB3')
         key_length = len(secret_key) * 8
         _key = sym_key.SymmetricKey('AES',
@@ -527,7 +568,12 @@ class BarbicanKeyManagerTestCase(test_ke
         self.assertRaises(exception.KeyManagerError,
                           self.key_mgr.store, self.ctxt, _key)
 
-    def test_get_active_order(self):
+    @mock.patch('castellan.key_manager.barbican_key_manager.'
+                'BarbicanKeyManager._get_barbican_client')
+    def test_get_active_order(self, mock_get_client):
+        mock_client = mock.Mock()
+        mock_get_client.return_value = (mock_client, self.base_url)
+
         order_ref_url = ("http://localhost:9311/v1/orders/"
                          "4fe939b7-72bc-49aa-bd1e-e979589858af")
 
@@ -540,17 +586,21 @@ class BarbicanKeyManagerTestCase(test_ke
         active_order.status = 'ACTIVE'
         active_order.order_ref = order_ref_url
 
-        self.mock_barbican.orders.get.side_effect = [pending_order,
-                                                     active_order]
+        mock_client.orders.get.side_effect = [pending_order, active_order]
 
-        self.key_mgr._get_active_order(self.mock_barbican, order_ref_url)
+        self.key_mgr._get_active_order(mock_client, order_ref_url)
 
-        self.assertEqual(2, self.mock_barbican.orders.get.call_count)
+        self.assertEqual(2, mock_client.orders.get.call_count)
 
         calls = [mock.call(order_ref_url), mock.call(order_ref_url)]
-        self.mock_barbican.orders.get.assert_has_calls(calls)
+        mock_client.orders.get.assert_has_calls(calls)
+
+    @mock.patch('castellan.key_manager.barbican_key_manager.'
+                'BarbicanKeyManager._get_barbican_client')
+    def test_get_active_order_timeout(self, mock_get_client):
+        mock_client = mock.Mock()
+        mock_get_client.return_value = (mock_client, self.base_url)
 
-    def test_get_active_order_timeout(self):
         order_ref_url = ("http://localhost:9311/v1/orders/"
                          "4fe939b7-72bc-49aa-bd1e-e979589858af")
 
@@ -560,17 +610,22 @@ class BarbicanKeyManagerTestCase(test_ke
         pending_order.status = 'PENDING'
         pending_order.order_ref = order_ref_url
 
-        self.mock_barbican.orders.get.return_value = pending_order
+        mock_client.orders.get.return_value = pending_order
 
         self.assertRaises(exception.KeyManagerError,
                           self.key_mgr._get_active_order,
-                          self.mock_barbican,
+                          mock_client,
                           order_ref_url)
 
         self.assertEqual(number_of_retries + 1,
-                         self.mock_barbican.orders.get.call_count)
+                         mock_client.orders.get.call_count)
+
+    @mock.patch('castellan.key_manager.barbican_key_manager.'
+                'BarbicanKeyManager._get_barbican_client')
+    def test_get_active_order_error(self, mock_get_client):
+        mock_client = mock.Mock()
+        mock_get_client.return_value = (mock_client, self.base_url)
 
-    def test_get_active_order_error(self):
         order_ref_url = ("http://localhost:9311/v1/orders/"
                          "4fe939b7-72bc-49aa-bd1e-e979589858af")
 
@@ -580,21 +635,25 @@ class BarbicanKeyManagerTestCase(test_ke
         error_order.error_status_code = u"500"
         error_order.error_reason = u"Test Error"
 
-        self.mock_barbican.orders.get.return_value = error_order
+        mock_client.orders.get.return_value = error_order
 
         self.assertRaises(exception.KeyManagerError,
                           self.key_mgr._get_active_order,
-                          self.mock_barbican,
+                          mock_client,
                           order_ref_url)
 
-        self.assertEqual(1, self.mock_barbican.orders.get.call_count)
+        self.assertEqual(1, mock_client.orders.get.call_count)
 
     def test_list_null_context(self):
-        self.key_mgr._barbican_client = None
         self.assertRaises(exception.Forbidden,
                           self.key_mgr.list, None)
 
-    def test_list(self):
+    @mock.patch('castellan.key_manager.barbican_key_manager.'
+                'BarbicanKeyManager._get_barbican_client')
+    def test_list(self, mock_get_client):
+        mock_client = mock.Mock()
+        mock_get_client.return_value = (mock_client, self.base_url)
+
         original_secret_metadata = mock.Mock()
         original_secret_metadata.algorithm = mock.sentinel.alg
         original_secret_metadata.bit_length = mock.sentinel.bit
@@ -615,7 +674,7 @@ class BarbicanKeyManagerTestCase(test_ke
         original_secret_data = b'test key'
         original_secret_metadata.payload = original_secret_data
 
-        self.mock_barbican.secrets.list.return_value = (
+        mock_client.secrets.list.return_value = (
             [original_secret_metadata])
 
         # check metadata_only = False
@@ -623,26 +682,30 @@ class BarbicanKeyManagerTestCase(test_ke
         self.assertEqual(1, len(key_list))
         key = key_list[0]
 
-        self.list.assert_called_once()
+        mock_client.secrets.list.assert_called_once()
         self.assertEqual(key_id, key.id)
         self.assertEqual(key_name, key.name)
         self.assertEqual(original_secret_data, key.get_encoded())
         self.assertEqual(created_posix, key.created)
 
-        self.list.reset_mock()
+        mock_client.secrets.list.reset_mock()
 
         # check metadata_only = True
         key_list = self.key_mgr.list(self.ctxt, metadata_only=True)
         self.assertEqual(1, len(key_list))
         key = key_list[0]
 
-        self.list.assert_called_once()
+        mock_client.secrets.list.assert_called_once()
         self.assertEqual(key_name, key.name)
         self.assertIsNone(key.get_encoded())
         self.assertEqual(created_posix, key.created)
 
-    def test_list_with_error(self):
-        self.mock_barbican.secrets.list = mock.Mock(
+    @mock.patch('castellan.key_manager.barbican_key_manager.'
+                'BarbicanKeyManager._get_barbican_client')
+    def test_list_with_error(self, mock_get_client):
+        mock_client = mock.Mock()
+        mock_get_client.return_value = (mock_client, self.base_url)
+        mock_client.secrets.list = mock.Mock(
             side_effect=barbican_exceptions.HTTPClientError('test error'))
         self.assertRaises(exception.KeyManagerError,
                           self.key_mgr.list, self.ctxt)
@@ -673,41 +736,28 @@ class BarbicanKeyManagerTestCase(test_ke
         self.assertRaises(
             Error, method, ctxt, obj_ref, consumer_data)
 
-    def _mock_list_versions_and_test_consumer_expects_error(
-            self, Error, method, ctxt, obj_ref, service="storage",
-            resource_type='volume', resource_id=uuidutils.generate_uuid()):
-        self._mock_list_versions()
-        self._test_consumer_expects_error(
-            Error, method, ctxt, obj_ref, service=service,
-            resource_type=resource_type, resource_id=resource_id)
-
-    def _mock_list_versions_and_test_add_consumer_expects_error(
-            self, Error, ctxt, obj_ref, side_effect=None, service="storage",
-            resource_type='volume', resource_id=uuidutils.generate_uuid()):
-        self.mock_barbican.secrets.register_consumer = mock.Mock(
+    def _test_add_consumer_expects_error(
+            self, mock_client, Error, ctxt, obj_ref, side_effect=None,
+            service="storage", resource_type='volume',
+            resource_id=uuidutils.generate_uuid()):
+        mock_client.secrets.register_consumer = mock.Mock(
             side_effect=side_effect)
-        self._mock_list_versions_and_test_consumer_expects_error(
+        self._test_consumer_expects_error(
             Error, self.key_mgr.add_consumer, ctxt,
             obj_ref, service=service, resource_type=resource_type,
             resource_id=resource_id)
 
-    def _mock_list_versions_and_test_remove_consumer_expects_error(
-            self, Error, ctxt, obj_ref, side_effect=None, service="storage",
-            resource_type='volume', resource_id=uuidutils.generate_uuid()):
-        self.mock_barbican.secrets.remove_consumer = mock.Mock(
+    def _test_remove_consumer_expects_error(
+            self, mock_client, Error, ctxt, obj_ref, side_effect=None,
+            service="storage", resource_type='volume',
+            resource_id=uuidutils.generate_uuid()):
+        mock_client.secrets.remove_consumer = mock.Mock(
             side_effect=side_effect)
-        self._mock_list_versions_and_test_consumer_expects_error(
+        self._test_consumer_expects_error(
             Error, self.key_mgr.remove_consumer, ctxt,
             obj_ref, service=service, resource_type=resource_type,
             resource_id=resource_id)
 
-    def _mock_list_versions(self):
-        list_versions = [{
-            'id': 'v1', 'status': 'CURRENT', 'min_version': '1.0',
-            'max_version': '1.1', 'links': []}
-        ]
-        self.list_versions.return_value = list_versions
-
     def _get_custom_consumer_data(
             self, service="storage", resource_type='volume',
             resource_id=uuidutils.generate_uuid()):
@@ -716,192 +766,330 @@ class BarbicanKeyManagerTestCase(test_ke
             'resource_id': resource_id}
 
     def test_add_consumer_without_context_fails(self):
-        self.key_mgr._barbican_client = None
         self._test_consumer_expects_error(
             exception.Forbidden, self.key_mgr.add_consumer, None,
             self.secret_ref)
 
-    def test_add_consumer_with_different_project_fails(self):
+    @mock.patch('castellan.key_manager.barbican_key_manager.'
+                'BarbicanKeyManager._get_barbican_client')
+    def test_add_consumer_with_different_project_fails(self, mock_get_client):
+        mock_client = mock.Mock()
+        mock_get_client.return_value = (mock_client, self.base_url)
+
         side_effect = barbican_exceptions.HTTPClientError(
             "Forbidden: SecretConsumer creation attempt not allowed - "
             "please review your user/project privileges")
-        self._mock_list_versions_and_test_add_consumer_expects_error(
-            exception.KeyManagerError, self.ctxt, self.secret_ref,
+        self._test_add_consumer_expects_error(
+            mock_client, exception.KeyManagerError, self.ctxt, self.secret_ref,
             side_effect=side_effect)
 
-    def test_add_consumer_with_null_managed_object_id_fails(self):
-        self._mock_list_versions_and_test_add_consumer_expects_error(
-            exception.KeyManagerError, self.ctxt, None)
-
-    def test_add_consumer_with_empty_managed_object_id_fails(self):
-        self._mock_list_versions_and_test_add_consumer_expects_error(
-            exception.KeyManagerError, self.ctxt, "")
+    @mock.patch('castellan.key_manager.barbican_key_manager.'
+                'BarbicanKeyManager._get_barbican_client')
+    def test_add_consumer_with_null_managed_object_id_fails(
+            self, mock_get_client):
+        mock_client = mock.Mock()
+        mock_get_client.return_value = (mock_client, self.base_url)
+
+        self._test_add_consumer_expects_error(
+            mock_client, exception.KeyManagerError, self.ctxt, None)
+
+    @mock.patch('castellan.key_manager.barbican_key_manager.'
+                'BarbicanKeyManager._get_barbican_client')
+    def test_add_consumer_with_empty_managed_object_id_fails(
+            self, mock_get_client):
+        mock_client = mock.Mock()
+        mock_get_client.return_value = (mock_client, self.base_url)
+
+        self._test_add_consumer_expects_error(
+            mock_client, exception.KeyManagerError, self.ctxt, "")
+
+    @mock.patch('castellan.key_manager.barbican_key_manager.'
+                'BarbicanKeyManager._get_barbican_client')
+    def test_add_consumer_with_invalid_managed_object_id_fails(
+            self, mock_get_client):
+        mock_client = mock.Mock()
+        mock_get_client.return_value = (mock_client, self.base_url)
 
-    def test_add_consumer_with_invalid_managed_object_id_fails(self):
         side_effect = ValueError("Secret incorrectly specified.")
-        self._mock_list_versions_and_test_add_consumer_expects_error(
-            ValueError, self.ctxt, uuidutils.generate_uuid()[:-1],
+        self._test_add_consumer_expects_error(
+            mock_client, ValueError, self.ctxt, uuidutils.generate_uuid()[:-1],
             side_effect=side_effect)
 
-    def test_add_consumer_with_inexistent_managed_object_id_fails(self):
+    @mock.patch('castellan.key_manager.barbican_key_manager.'
+                'BarbicanKeyManager._get_barbican_client')
+    def test_add_consumer_with_inexistent_managed_object_id_fails(
+            self, mock_get_client):
+        mock_client = mock.Mock()
+        mock_get_client.return_value = (mock_client, self.base_url)
+
         side_effect = barbican_exceptions.HTTPClientError(
             "Not Found: Secret not found.", status_code=404)
-        self._mock_list_versions_and_test_add_consumer_expects_error(
-            exception.ManagedObjectNotFoundError, self.ctxt, self.secret_ref,
-            side_effect=side_effect)
+        self._test_add_consumer_expects_error(
+            mock_client, exception.ManagedObjectNotFoundError, self.ctxt,
+            self.secret_ref, side_effect=side_effect)
+
+    @mock.patch('castellan.key_manager.barbican_key_manager.'
+                'BarbicanKeyManager._get_barbican_client')
+    def test_add_consumer_with_null_service_fails(
+            self, mock_get_client):
+        mock_client = mock.Mock()
+        mock_get_client.return_value = (mock_client, self.base_url)
 
-    def test_add_consumer_with_null_service_fails(self):
         side_effect = barbican_exceptions.HTTPClientError(
             "Bad Request: Provided object does not match schema "
             "'Secret Consumer': None is not of type 'string'. Invalid "
             "property: 'service'", status_code=400)
-        self._mock_list_versions_and_test_add_consumer_expects_error(
-            exception.KeyManagerError, self.ctxt, self.secret_ref,
+        self._test_add_consumer_expects_error(
+            mock_client, exception.KeyManagerError, self.ctxt, self.secret_ref,
             side_effect=side_effect, service=None)
 
-    def test_add_consumer_with_empty_service_fails(self):
+    @mock.patch('castellan.key_manager.barbican_key_manager.'
+                'BarbicanKeyManager._get_barbican_client')
+    def test_add_consumer_with_empty_service_fails(
+            self, mock_get_client):
+        mock_client = mock.Mock()
+        mock_get_client.return_value = (mock_client, self.base_url)
+
         side_effect = barbican_exceptions.HTTPClientError(
             "Bad Request: Provided object does not match schema "
             "'Secret Consumer': '' is too short. Invalid property: 'service'",
             status_code=400)
-        self._mock_list_versions_and_test_add_consumer_expects_error(
-            exception.KeyManagerError, self.ctxt, self.secret_ref,
+        self._test_add_consumer_expects_error(
+            mock_client, exception.KeyManagerError, self.ctxt, self.secret_ref,
             side_effect=side_effect, service="")
 
-    def test_add_consumer_with_null_resource_type_fails(self):
+    @mock.patch('castellan.key_manager.barbican_key_manager.'
+                'BarbicanKeyManager._get_barbican_client')
+    def test_add_consumer_with_null_resource_type_fails(
+            self, mock_get_client):
+        mock_client = mock.Mock()
+        mock_get_client.return_value = (mock_client, self.base_url)
+
         side_effect = barbican_exceptions.HTTPClientError(
             "Bad Request: Provided object does not match schema "
             "'Secret Consumer': None is not of type 'string'. "
             "Invalid property: 'resource_type'", status_code=400)
-        self._mock_list_versions_and_test_add_consumer_expects_error(
-            exception.KeyManagerError, self.ctxt, self.secret_ref,
+        self._test_add_consumer_expects_error(
+            mock_client, exception.KeyManagerError, self.ctxt, self.secret_ref,
             side_effect=side_effect, resource_type=None)
 
-    def test_add_consumer_with_empty_resource_type_fails(self):
+    @mock.patch('castellan.key_manager.barbican_key_manager.'
+                'BarbicanKeyManager._get_barbican_client')
+    def test_add_consumer_with_empty_resource_type_fails(
+            self, mock_get_client):
+        mock_client = mock.Mock()
+        mock_get_client.return_value = (mock_client, self.base_url)
+
         side_effect = barbican_exceptions.HTTPClientError(
             "Bad Request: Provided object does not match schema "
             "'Secret Consumer': '' is too short. Invalid property: "
             "'resource_type'", status_code=400)
-        self._mock_list_versions_and_test_add_consumer_expects_error(
-            exception.KeyManagerError, self.ctxt, self.secret_ref,
+        self._test_add_consumer_expects_error(
+            mock_client, exception.KeyManagerError, self.ctxt, self.secret_ref,
             side_effect=side_effect, resource_type="")
 
-    def test_add_consumer_with_null_resource_id_fails(self):
+    @mock.patch('castellan.key_manager.barbican_key_manager.'
+                'BarbicanKeyManager._get_barbican_client')
+    def test_add_consumer_with_null_resource_id_fails(
+            self, mock_get_client):
+        mock_client = mock.Mock()
+        mock_get_client.return_value = (mock_client, self.base_url)
+
         side_effect = barbican_exceptions.HTTPClientError(
             "Bad Request: Provided object does not match schema "
             "'Secret Consumer': None is not of type 'string'. "
             "Invalid property: 'resource_id'", status_code=400)
-        self._mock_list_versions_and_test_add_consumer_expects_error(
-            exception.KeyManagerError, self.ctxt, self.secret_ref,
+        self._test_add_consumer_expects_error(
+            mock_client, exception.KeyManagerError, self.ctxt, self.secret_ref,
             side_effect=side_effect, resource_id=None)
 
-    def test_add_consumer_with_empty_resource_id_fails(self):
+    @mock.patch('castellan.key_manager.barbican_key_manager.'
+                'BarbicanKeyManager._get_barbican_client')
+    def test_add_consumer_with_empty_resource_id_fails(
+            self, mock_get_client):
+        mock_client = mock.Mock()
+        mock_get_client.return_value = (mock_client, self.base_url)
+
         side_effect = barbican_exceptions.HTTPClientError(
             "Bad Request: Provided object does not match schema "
             "'Secret Consumer': '' is too short. Invalid property: "
             "'resource_id'", status_code=400)
-        self._mock_list_versions_and_test_add_consumer_expects_error(
-            exception.KeyManagerError, self.ctxt, self.secret_ref,
+        self._test_add_consumer_expects_error(
+            mock_client, exception.KeyManagerError, self.ctxt, self.secret_ref,
             side_effect=side_effect, resource_id="")
 
-    def test_add_consumer_with_valid_parameters_doesnt_fail(self):
-        self._mock_list_versions()
+    @mock.patch('castellan.key_manager.barbican_key_manager.'
+                'BarbicanKeyManager._get_barbican_client')
+    def test_add_consumer_with_valid_parameters_doesnt_fail(
+            self, mock_get_client):
+        mock_client = mock.Mock()
+        mock_get_client.return_value = (mock_client, self.base_url)
+
         self.key_mgr.add_consumer(
             self.ctxt, self.secret_ref, self._get_custom_consumer_data())
 
     def test_remove_consumer_without_context_fails(self):
-        self.key_mgr._barbican_client = None
         self._test_consumer_expects_error(
-            exception.Forbidden, self.key_mgr.remove_consumer, None,
-            self.secret_ref)
+            exception.Forbidden, self.key_mgr.remove_consumer,
+            None, self.secret_ref)
+
+    @mock.patch('castellan.key_manager.barbican_key_manager.'
+                'BarbicanKeyManager._get_barbican_client')
+    def test_remove_consumer_with_different_project_fails(
+            self, mock_get_client):
+        mock_client = mock.Mock()
+        mock_get_client.return_value = (mock_client, self.base_url)
 
-    def test_remove_consumer_with_different_project_fails(self):
         side_effect = barbican_exceptions.HTTPClientError(
             "Forbidden: SecretConsumer creation attempt not allowed - "
             "please review your user/project privileges")
-        self._mock_list_versions_and_test_remove_consumer_expects_error(
-            exception.KeyManagerError, self.ctxt, self.secret_ref,
+        self._test_remove_consumer_expects_error(
+            mock_client, exception.KeyManagerError, self.ctxt, self.secret_ref,
             side_effect=side_effect)
 
-    def test_remove_consumer_with_null_managed_object_id_fails(self):
+    @mock.patch('castellan.key_manager.barbican_key_manager.'
+                'BarbicanKeyManager._get_barbican_client')
+    def test_remove_consumer_with_null_managed_object_id_fails(
+            self, mock_get_client):
+        mock_client = mock.Mock()
+        mock_get_client.return_value = (mock_client, self.base_url)
+
         side_effect = ValueError("secret incorrectly specified.")
-        self._mock_list_versions_and_test_add_consumer_expects_error(
-            exception.KeyManagerError, self.ctxt, None,
+        self._test_add_consumer_expects_error(
+            mock_client, exception.KeyManagerError, self.ctxt, None,
             side_effect=side_effect)
 
-    def test_remove_consumer_with_empty_managed_object_id_fails(self):
+    @mock.patch('castellan.key_manager.barbican_key_manager.'
+                'BarbicanKeyManager._get_barbican_client')
+    def test_remove_consumer_with_empty_managed_object_id_fails(
+            self, mock_get_client):
+        mock_client = mock.Mock()
+        mock_get_client.return_value = (mock_client, self.base_url)
+
         side_effect = ValueError("secret incorrectly specified.")
-        self._mock_list_versions_and_test_add_consumer_expects_error(
-            exception.KeyManagerError, self.ctxt, "", side_effect=side_effect)
+        self._test_add_consumer_expects_error(
+            mock_client, exception.KeyManagerError, self.ctxt, "",
+            side_effect=side_effect)
+
+    @mock.patch('castellan.key_manager.barbican_key_manager.'
+                'BarbicanKeyManager._get_barbican_client')
+    def test_remove_consumer_with_invalid_managed_object_id_fails(
+            self, mock_get_client):
+        mock_client = mock.Mock()
+        mock_get_client.return_value = (mock_client, self.base_url)
 
-    def test_remove_consumer_with_invalid_managed_object_id_fails(self):
         side_effect = ValueError("Secret incorrectly specified.")
-        self._mock_list_versions_and_test_add_consumer_expects_error(
-            ValueError, self.ctxt, uuidutils.generate_uuid()[:-1],
+        self._test_add_consumer_expects_error(
+            mock_client, ValueError, self.ctxt, uuidutils.generate_uuid()[:-1],
             side_effect=side_effect)
 
-    def test_remove_consumer_without_registered_managed_object_id_fails(self):
+    @mock.patch('castellan.key_manager.barbican_key_manager.'
+                'BarbicanKeyManager._get_barbican_client')
+    def test_remove_consumer_without_registered_managed_object_id_fails(
+            self, mock_get_client):
+        mock_client = mock.Mock()
+        mock_get_client.return_value = (mock_client, self.base_url)
+
         side_effect = barbican_exceptions.HTTPClientError(
             "Not Found: Secret not found.", status_code=404)
-        self._mock_list_versions_and_test_add_consumer_expects_error(
-            exception.ManagedObjectNotFoundError, self.ctxt, self.secret_ref,
-            side_effect=side_effect)
+        self._test_add_consumer_expects_error(
+            mock_client, exception.ManagedObjectNotFoundError, self.ctxt,
+            self.secret_ref, side_effect=side_effect)
+
+    @mock.patch('castellan.key_manager.barbican_key_manager.'
+                'BarbicanKeyManager._get_barbican_client')
+    def test_remove_consumer_with_null_service_fails(self, mock_get_client):
+        mock_client = mock.Mock()
+        mock_get_client.return_value = (mock_client, self.base_url)
 
-    def test_remove_consumer_with_null_service_fails(self):
         side_effect = barbican_exceptions.HTTPClientError(
             "Bad Request: Provided object does not match schema "
             "'Secret Consumer': None is not of type 'string'. Invalid "
             "property: 'service'", status_code=400)
-        self._mock_list_versions_and_test_add_consumer_expects_error(
-            exception.KeyManagerError, self.ctxt, self.secret_ref,
+        self._test_add_consumer_expects_error(
+            mock_client, exception.KeyManagerError, self.ctxt, self.secret_ref,
             side_effect=side_effect, service=None)
 
-    def test_remove_consumer_with_empty_service_fails(self):
+    @mock.patch('castellan.key_manager.barbican_key_manager.'
+                'BarbicanKeyManager._get_barbican_client')
+    def test_remove_consumer_with_empty_service_fails(
+            self, mock_get_client):
+        mock_client = mock.Mock()
+        mock_get_client.return_value = (mock_client, self.base_url)
+
         side_effect = barbican_exceptions.HTTPClientError(
             "Bad Request: Provided object does not match schema "
             "'Secret Consumer': '' is too short. Invalid property: 'service'",
             status_code=400)
-        self._mock_list_versions_and_test_add_consumer_expects_error(
-            exception.KeyManagerError, self.ctxt, self.secret_ref,
+        self._test_add_consumer_expects_error(
+            mock_client, exception.KeyManagerError, self.ctxt, self.secret_ref,
             side_effect=side_effect, service="")
 
-    def test_remove_consumer_with_null_resource_type_fails(self):
+    @mock.patch('castellan.key_manager.barbican_key_manager.'
+                'BarbicanKeyManager._get_barbican_client')
+    def test_remove_consumer_with_null_resource_type_fails(
+            self, mock_get_client):
+        mock_client = mock.Mock()
+        mock_get_client.return_value = (mock_client, self.base_url)
+
         side_effect = barbican_exceptions.HTTPClientError(
             "Bad Request: Provided object does not match schema "
             "'Secret Consumer': None is not of type 'string'. "
             "Invalid property: 'resource_type'", status_code=400)
-        self._mock_list_versions_and_test_add_consumer_expects_error(
-            exception.KeyManagerError, self.ctxt, self.secret_ref,
+        self._test_add_consumer_expects_error(
+            mock_client, exception.KeyManagerError, self.ctxt, self.secret_ref,
             side_effect=side_effect, resource_type=None)
 
-    def test_remove_consumer_with_empty_resource_type_fails(self):
+    @mock.patch('castellan.key_manager.barbican_key_manager.'
+                'BarbicanKeyManager._get_barbican_client')
+    def test_remove_consumer_with_empty_resource_type_fails(
+            self, mock_get_client):
+        mock_client = mock.Mock()
+        mock_get_client.return_value = (mock_client, self.base_url)
+
         side_effect = barbican_exceptions.HTTPClientError(
             "Bad Request: Provided object does not match schema "
             "'Secret Consumer': '' is too short. Invalid property: "
             "'resource_type'", status_code=400)
-        self._mock_list_versions_and_test_add_consumer_expects_error(
-            exception.KeyManagerError, self.ctxt, self.secret_ref,
+        self._test_add_consumer_expects_error(
+            mock_client, exception.KeyManagerError, self.ctxt, self.secret_ref,
             side_effect=side_effect, resource_type="")
 
-    def test_remove_consumer_with_null_resource_id_fails(self):
+    @mock.patch('castellan.key_manager.barbican_key_manager.'
+                'BarbicanKeyManager._get_barbican_client')
+    def test_remove_consumer_with_null_resource_id_fails(
+            self, mock_get_client):
+        mock_client = mock.Mock()
+        mock_get_client.return_value = (mock_client, self.base_url)
+
         side_effect = barbican_exceptions.HTTPClientError(
             "Bad Request: Provided object does not match schema "
             "'Secret Consumer': None is not of type 'string'. "
             "Invalid property: 'resource_id'", status_code=400)
-        self._mock_list_versions_and_test_add_consumer_expects_error(
-            exception.KeyManagerError, self.ctxt, self.secret_ref,
+        self._test_add_consumer_expects_error(
+            mock_client, exception.KeyManagerError, self.ctxt, self.secret_ref,
             side_effect=side_effect, resource_id=None)
 
-    def test_remove_consumer_with_empty_resource_id_fails(self):
+    @mock.patch('castellan.key_manager.barbican_key_manager.'
+                'BarbicanKeyManager._get_barbican_client')
+    def test_remove_consumer_with_empty_resource_id_fails(
+            self, mock_get_client):
+        mock_client = mock.Mock()
+        mock_get_client.return_value = (mock_client, self.base_url)
+
         side_effect = barbican_exceptions.HTTPClientError(
             "Bad Request: Provided object does not match schema "
             "'Secret Consumer': '' is too short. Invalid property: "
             "'resource_id'", status_code=400)
-        self._mock_list_versions_and_test_add_consumer_expects_error(
-            exception.KeyManagerError, self.ctxt, self.secret_ref,
+        self._test_add_consumer_expects_error(
+            mock_client, exception.KeyManagerError, self.ctxt, self.secret_ref,
             side_effect=side_effect, resource_id="")
 
-    def test_remove_consumer_with_valid_parameters_doesnt_fail(self):
-        self._mock_list_versions()
+    @mock.patch('castellan.key_manager.barbican_key_manager.'
+                'BarbicanKeyManager._get_barbican_client')
+    def test_remove_consumer_with_valid_parameters_doesnt_fail(
+            self, mock_get_client):
+        mock_client = mock.Mock()
+        mock_get_client.return_value = (mock_client, self.base_url)
         self.key_mgr.remove_consumer(
             self.ctxt, self.secret_ref, self._get_custom_consumer_data())
diff -pruN 5.2.1-2/debian/changelog 5.4.1-1/debian/changelog
--- 5.2.1-2/debian/changelog	2025-03-28 06:53:20.000000000 +0000
+++ 5.4.1-1/debian/changelog	2025-08-28 09:50:40.000000000 +0000
@@ -1,3 +1,9 @@
+python-castellan (5.4.1-1) experimental; urgency=medium
+
+  * New upstream release.
+
+ -- Thomas Goirand <zigo@debian.org>  Thu, 28 Aug 2025 11:50:40 +0200
+
 python-castellan (5.2.1-2) unstable; urgency=medium
 
   * Uploading to unstable.
diff -pruN 5.2.1-2/pyproject.toml 5.4.1-1/pyproject.toml
--- 5.2.1-2/pyproject.toml	1970-01-01 00:00:00.000000000 +0000
+++ 5.4.1-1/pyproject.toml	2025-07-10 14:54:06.000000000 +0000
@@ -0,0 +1,3 @@
+[build-system]
+requires = ["pbr>=6.1.1"]
+build-backend = "pbr.build"
diff -pruN 5.2.1-2/releasenotes/source/2025.1.rst 5.4.1-1/releasenotes/source/2025.1.rst
--- 5.2.1-2/releasenotes/source/2025.1.rst	1970-01-01 00:00:00.000000000 +0000
+++ 5.4.1-1/releasenotes/source/2025.1.rst	2025-07-10 14:54:06.000000000 +0000
@@ -0,0 +1,6 @@
+===========================
+2025.1 Series Release Notes
+===========================
+
+.. release-notes::
+   :branch: stable/2025.1
diff -pruN 5.2.1-2/releasenotes/source/index.rst 5.4.1-1/releasenotes/source/index.rst
--- 5.2.1-2/releasenotes/source/index.rst	2025-02-15 06:32:57.000000000 +0000
+++ 5.4.1-1/releasenotes/source/index.rst	2025-07-10 14:54:06.000000000 +0000
@@ -6,6 +6,7 @@
    :maxdepth: 1
 
    unreleased
+   2025.1
    2024.2
    2024.1
    2023.2
diff -pruN 5.2.1-2/test-requirements.txt 5.4.1-1/test-requirements.txt
--- 5.2.1-2/test-requirements.txt	2025-02-15 06:32:57.000000000 +0000
+++ 5.4.1-1/test-requirements.txt	2025-07-10 14:54:06.000000000 +0000
@@ -1,7 +1,6 @@
 coverage>=4.0 # Apache-2.0
 python-barbicanclient>=4.5.2 # Apache-2.0
 requests-mock>=1.2.0 # Apache-2.0
-python-subunit>=1.0.0 # Apache-2.0/BSD
 oslotest>=3.2.0 # Apache-2.0
 stestr>=2.0.0 # Apache-2.0
 fixtures>=3.0.0 # Apache-2.0/BSD
diff -pruN 5.2.1-2/tox.ini 5.4.1-1/tox.ini
--- 5.2.1-2/tox.ini	2025-02-15 06:32:57.000000000 +0000
+++ 5.4.1-1/tox.ini	2025-07-10 14:54:06.000000000 +0000
@@ -1,13 +1,10 @@
 [tox]
-minversion = 3.18.0
+minversion = 4.0.0
 envlist = py3,pep8
-ignore_basepython_conflict = True
 
 [testenv]
 usedevelop = True
-basepython = python3
 setenv =
-  VIRTUAL_ENV={envdir}
   OS_TEST_PATH=./castellan/tests/unit
 deps =
   -c{env:TOX_CONSTRAINTS_FILE:https://releases.openstack.org/constraints/upper/master}
@@ -30,14 +27,14 @@ commands = oslo_debug_helper {posargs}
 
 [testenv:cover]
 setenv =
-    PYTHON=coverage run --source castellan --parallel-mode
+  PYTHON=coverage run --source castellan --parallel-mode
 commands =
-    coverage erase
-    {[testenv]commands}
-    coverage combine
-    coverage html -d cover
-    coverage xml -o cover/coverage.xml
-    coverage report --show-missing
+  coverage erase
+  {[testenv]commands}
+  coverage combine
+  coverage html -d cover
+  coverage xml -o cover/coverage.xml
+  coverage report --show-missing
 
 [testenv:docs]
 # This environment is called from CI scripts to test and publish
@@ -68,25 +65,23 @@ commands = sphinx-build -a -E -W -d rele
 [testenv:functional]
 usedevelop = True
 setenv =
-    VIRTUAL_ENV={envdir}
-    OS_TEST_PATH=./castellan/tests/functional
+  OS_TEST_PATH=./castellan/tests/functional
 commands = stestr run --slowest --concurrency=1 {posargs}
 
 [testenv:functional-vault]
 passenv = HOME
 usedevelop = True
 setenv =
-    VIRTUAL_ENV={envdir}
-    OS_TEST_PATH=./castellan/tests/functional
+  OS_TEST_PATH=./castellan/tests/functional
 commands =
-    {toxinidir}/tools/setup-vault-env.sh pifpaf -e VAULT_TEST run vault -- stestr run --concurrency=1 --slowest {posargs}
+  {toxinidir}/tools/setup-vault-env.sh pifpaf -e VAULT_TEST run vault -- stestr run --concurrency=1 --slowest {posargs}
 allowlist_externals =
   {toxinidir}/tools/setup-vault-env.sh
 
 [testenv:genconfig]
 commands =
-    oslo-config-generator --config-file=etc/castellan/functional-config-generator.conf
-    oslo-config-generator --config-file=etc/castellan/sample-config-generator.conf
+  oslo-config-generator --config-file=etc/castellan/functional-config-generator.conf
+  oslo-config-generator --config-file=etc/castellan/sample-config-generator.conf
 
 [flake8]
 # [H106] Don't put vim configuration in source files.
