summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Tantsur <dtantsur@protonmail.com>2022-10-31 11:19:08 +0100
committerDmitry Tantsur <dtantsur@protonmail.com>2022-10-31 11:19:08 +0100
commitcab51a9fcc022f2e4bb634277dd20e90e2dc78f7 (patch)
tree62f933f2fcfb9a626ea6f706132b49f4771fd217
parent5d5ae595380ac506eeb6a369e26efaed338790d1 (diff)
downloadironic-cab51a9fcc022f2e4bb634277dd20e90e2dc78f7.tar.gz
Fix the invalid glance client test
It relied on mocking tenacity.retry, but it's executed on class initialization. Depending on the ordering, it may do nothing or it may replace ImageService.call with a mock. Instead, add a new tenacity helper that loads an option in runtime. As a nice side effect, [glance]num_retries is now mutable. Change-Id: I2e02231d294997e824db77c998ef8d352fa69075
-rw-r--r--ironic/common/glance_service/image_service.py3
-rw-r--r--ironic/common/utils.py15
-rw-r--r--ironic/conf/glance.py1
-rw-r--r--ironic/tests/unit/common/test_glance_service.py27
4 files changed, 30 insertions, 16 deletions
diff --git a/ironic/common/glance_service/image_service.py b/ironic/common/glance_service/image_service.py
index 0a32eaf0a..1d9d6d4bc 100644
--- a/ironic/common/glance_service/image_service.py
+++ b/ironic/common/glance_service/image_service.py
@@ -33,6 +33,7 @@ from ironic.common.glance_service import service_utils
from ironic.common.i18n import _
from ironic.common import keystone
from ironic.common import swift
+from ironic.common import utils
from ironic.conf import CONF
TempUrlCacheElement = collections.namedtuple('TempUrlCacheElement',
@@ -114,7 +115,7 @@ class GlanceImageService(object):
@tenacity.retry(
retry=tenacity.retry_if_exception_type(
exception.GlanceConnectionFailed),
- stop=tenacity.stop_after_attempt(CONF.glance.num_retries + 1),
+ stop=utils.stop_after_retries('num_retries', group='glance'),
wait=tenacity.wait_fixed(1),
reraise=True
)
diff --git a/ironic/common/utils.py b/ironic/common/utils.py
index e4d83c9b6..9ae88d4d6 100644
--- a/ironic/common/utils.py
+++ b/ironic/common/utils.py
@@ -681,3 +681,18 @@ def is_fips_enabled():
except Exception:
pass
return False
+
+
+def stop_after_retries(option, group=None):
+ """A tenacity retry helper that stops after retries specified in conf."""
+ # NOTE(dtantsur): fetch the option inside of the nested call, otherwise it
+ # cannot be changed in runtime.
+ def should_stop(retry_state):
+ if group:
+ conf = getattr(CONF, group)
+ else:
+ conf = CONF
+ num_retries = getattr(conf, option)
+ return retry_state.attempt_number >= num_retries + 1
+
+ return should_stop
diff --git a/ironic/conf/glance.py b/ironic/conf/glance.py
index a3286b1eb..317f213bc 100644
--- a/ironic/conf/glance.py
+++ b/ironic/conf/glance.py
@@ -114,6 +114,7 @@ opts = [
'will determine how many containers are created.')),
cfg.IntOpt('num_retries',
default=0,
+ mutable=True,
help=_('Number of retries when downloading an image from '
'glance.')),
]
diff --git a/ironic/tests/unit/common/test_glance_service.py b/ironic/tests/unit/common/test_glance_service.py
index 327125a81..f9e713e91 100644
--- a/ironic/tests/unit/common/test_glance_service.py
+++ b/ironic/tests/unit/common/test_glance_service.py
@@ -24,7 +24,6 @@ from glanceclient import exc as glance_exc
from keystoneauth1 import loading as ks_loading
from oslo_config import cfg
from oslo_utils import uuidutils
-import tenacity
import testtools
from ironic.common import context
@@ -202,20 +201,18 @@ class TestGlanceImageService(base.TestCase):
image_id = uuidutils.generate_uuid()
writer = NullWriter()
- with mock.patch.object(tenacity, 'retry', autospec=True) as mock_retry:
- # When retries are disabled, we should get an exception
- self.config(num_retries=0, group='glance')
- self.assertRaises(exception.GlanceConnectionFailed,
- stub_service.download, image_id, writer)
-
- # Now lets enable retries. No exception should happen now.
- self.config(num_retries=1, group='glance')
- importlib.reload(image_service)
- stub_service = image_service.GlanceImageService(stub_client,
- stub_context)
- tries = [0]
- stub_service.download(image_id, writer)
- mock_retry.assert_called_once()
+ # When retries are disabled, we should get an exception
+ self.config(num_retries=0, group='glance')
+ self.assertRaises(exception.GlanceConnectionFailed,
+ stub_service.download, image_id, writer)
+
+ # Now lets enable retries. No exception should happen now.
+ self.config(num_retries=1, group='glance')
+ importlib.reload(image_service)
+ stub_service = image_service.GlanceImageService(stub_client,
+ stub_context)
+ tries = [0]
+ stub_service.download(image_id, writer)
def test_download_no_data(self):
self.client.fake_wrapped = None