Modify UUID sentinel to support keystone-like UUIDs

Keystone User IDs and Project IDs are used in unit tests, but
_UUIDSentinels() class doesn't generate UUIDs without hyphens.

This patch makes backward compatible modifications to
_UUIDSentinels() class and introduces keystoneidsentinel global
that could be used in the same way as existing uuidsentinel.

Original "UUID sentinel" change: I214ff21b461fa1ca4b83476e1d0a763efe986217

Related-Bug: #1746747
Change-Id: Idb3e893cc03d64ad0522b5e4cedfa30c4f4a2a2f
This commit is contained in:
Alexey Stupnikov 2021-07-26 11:37:19 +00:00
parent 75c4abd909
commit 2c74bb92e5
3 changed files with 25 additions and 3 deletions

View File

@ -55,7 +55,8 @@ class TimeFixture(fixtures.Fixture):
class _UUIDSentinels(object): class _UUIDSentinels(object):
"""Registry of dynamically created, named, random UUID strings. """Registry of dynamically created, named, random UUID strings in regular
(with hyphens) and similar to some keystone IDs (without hyphens) formats.
An instance of this class will dynamically generate attributes as they are An instance of this class will dynamically generate attributes as they are
referenced, associating a random UUID string with each. Thereafter, referenced, associating a random UUID string with each. Thereafter,
@ -65,6 +66,7 @@ class _UUIDSentinels(object):
Usage:: Usage::
from oslo_utils.fixture import uuidsentinel as uuids from oslo_utils.fixture import uuidsentinel as uuids
from oslo_utils.fixture import keystoneidsentinel as keystids
... ...
foo = uuids.foo foo = uuids.foo
do_a_thing(foo) do_a_thing(foo)
@ -72,17 +74,22 @@ class _UUIDSentinels(object):
assert foo == uuids.foo assert foo == uuids.foo
# But a different one will be different # But a different one will be different
assert foo != uuids.bar assert foo != uuids.bar
# Same approach is valid for keystoneidsentinel:
data = create_some_data_structure(keystids.bar, var1, var2, var3)
assert extract_bar(data) == keystids.bar
""" """
def __init__(self): def __init__(self, is_dashed=True):
self._sentinels = {} self._sentinels = {}
self._lock = threading.Lock() self._lock = threading.Lock()
self.is_dashed = is_dashed
def __getattr__(self, name): def __getattr__(self, name):
if name.startswith('_'): if name.startswith('_'):
raise AttributeError('Sentinels must not start with _') raise AttributeError('Sentinels must not start with _')
with self._lock: with self._lock:
if name not in self._sentinels: if name not in self._sentinels:
self._sentinels[name] = uuidutils.generate_uuid() self._sentinels[name] = uuidutils.generate_uuid(
dashed=self.is_dashed)
return self._sentinels[name] return self._sentinels[name]
@ -90,3 +97,4 @@ class _UUIDSentinels(object):
# same process (including across multiple modules) will result in the same # same process (including across multiple modules) will result in the same
# values # values
uuidsentinel = _UUIDSentinels() uuidsentinel = _UUIDSentinels()
keystoneidsentinel = _UUIDSentinels(is_dashed=False)

View File

@ -19,6 +19,7 @@ import datetime
from oslotest import base as test_base from oslotest import base as test_base
from oslo_utils import fixture from oslo_utils import fixture
from oslo_utils.fixture import keystoneidsentinel as keystids
from oslo_utils.fixture import uuidsentinel as uuids from oslo_utils.fixture import uuidsentinel as uuids
from oslo_utils import timeutils from oslo_utils import timeutils
from oslo_utils import uuidutils from oslo_utils import uuidutils
@ -71,13 +72,20 @@ class UUIDSentinelsTest(test_base.BaseTestCase):
uuid1 = uuids.foobar uuid1 = uuids.foobar
uuid2 = uuids.barfoo uuid2 = uuids.barfoo
self.assertNotEqual(uuid1, uuid2) self.assertNotEqual(uuid1, uuid2)
keystid1 = keystids.foobar
keystid2 = keystids.barfoo
self.assertNotEqual(keystid1, keystid2)
def test_returns_uuid(self): def test_returns_uuid(self):
self.assertTrue(uuidutils.is_uuid_like(uuids.foo)) self.assertTrue(uuidutils.is_uuid_like(uuids.foo))
self.assertTrue(uuidutils.is_uuid_like(keystids.foo))
def test_returns_string(self): def test_returns_string(self):
self.assertIsInstance(uuids.foo, str) self.assertIsInstance(uuids.foo, str)
self.assertIsInstance(keystids.foo, str)
def test_with_underline_prefix(self): def test_with_underline_prefix(self):
ex = self.assertRaises(AttributeError, getattr, uuids, '_foo') ex = self.assertRaises(AttributeError, getattr, uuids, '_foo')
self.assertIn("Sentinels must not start with _", str(ex)) self.assertIn("Sentinels must not start with _", str(ex))
ex = self.assertRaises(AttributeError, getattr, keystids, '_foo')
self.assertIn("Sentinels must not start with _", str(ex))

View File

@ -0,0 +1,6 @@
---
features:
- |
keystoneidsentinel singleton was introduced to generate
random keystone-like UUIDs. New sentinel could be used in the same
way as existing uuidsentinel.