diff --git a/src/lib/utils/common.py b/src/lib/utils/common.py index 60ea5ee46..464359d73 100644 --- a/src/lib/utils/common.py +++ b/src/lib/utils/common.py @@ -97,7 +97,7 @@ UuidPattern = Annotated[ str, pydantic.Field( - pattern=f'^{UUID_REGEX}|{OLD_UUID_REGEX}|{GROUP_UUID_REGEX}$')] + pattern=f'^(?:{UUID_REGEX}|{OLD_UUID_REGEX}|{GROUP_UUID_REGEX})$')] WFID_REGEX = r'[a-zA-Z]([a-zA-Z0-9_-]*[a-zA-Z0-9])?-\d+$' RESOURCE_REGEX = r'(?P(\d+(?:\.\d+)?))(?P([a-zA-Z]*))' diff --git a/src/lib/utils/tests/test_common.py b/src/lib/utils/tests/test_common.py index d79b86401..190f7e8d5 100644 --- a/src/lib/utils/tests/test_common.py +++ b/src/lib/utils/tests/test_common.py @@ -783,6 +783,33 @@ def test_truncated(self): self.assertEqual(len(uid), 8) +class TestUuidPattern(unittest.TestCase): + """ Tests for UUID validation. """ + + def test_accepts_supported_uuid_formats(self): + adapter = pydantic.TypeAdapter(common.UuidPattern) + + for uuid_value in [ + 'a' * 32, + 'osmo-' + 'a' * 32, + 'abcdefghijklmnopqrstuvwxyz', + ]: + with self.subTest(uuid_value=uuid_value): + self.assertEqual(adapter.validate_python(uuid_value), uuid_value) + + def test_rejects_partial_or_uppercase_uuid_values(self): + adapter = pydantic.TypeAdapter(common.UuidPattern) + + for uuid_value in [ + 'a' * 32 + '-junk', + 'xxxabcdefghijklmnopqrstuvwxyzyyy', + 'A' * 32, + ]: + with self.subTest(uuid_value=uuid_value): + with self.assertRaises(pydantic.ValidationError): + adapter.validate_python(uuid_value) + + class TestConvertCpuUnit(unittest.TestCase): """ Tests for convert_cpu_unit. """