diff options
| author | Barry Warsaw | 2015-12-26 23:16:01 -0500 |
|---|---|---|
| committer | Barry Warsaw | 2015-12-26 23:16:01 -0500 |
| commit | 39fd2905cc34221ca2907f14f3f018190a3f62c5 (patch) | |
| tree | 01c0208e40ebcea025b933619714e08ea0b58912 /src | |
| parent | 0e11f68b74beef848255272a8010cad3ea96af91 (diff) | |
| download | mailman-39fd2905cc34221ca2907f14f3f018190a3f62c5.tar.gz mailman-39fd2905cc34221ca2907f14f3f018190a3f62c5.tar.zst mailman-39fd2905cc34221ca2907f14f3f018190a3f62c5.zip | |
Diffstat (limited to 'src')
| -rw-r--r-- | src/mailman/utilities/tests/test_uid.py | 84 | ||||
| -rw-r--r-- | src/mailman/utilities/uid.py | 15 |
2 files changed, 90 insertions, 9 deletions
diff --git a/src/mailman/utilities/tests/test_uid.py b/src/mailman/utilities/tests/test_uid.py new file mode 100644 index 000000000..28df1c4b4 --- /dev/null +++ b/src/mailman/utilities/tests/test_uid.py @@ -0,0 +1,84 @@ +# Copyright (C) 2015 by the Free Software Foundation, Inc. +# +# This file is part of GNU Mailman. +# +# GNU Mailman is free software: you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free +# Software Foundation, either version 3 of the License, or (at your option) +# any later version. +# +# GNU Mailman is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License along with +# GNU Mailman. If not, see <http://www.gnu.org/licenses/>. + +"""Test the uid module.""" + +__all__ = [ + 'TestUID', + ] + + +import os +import uuid +import unittest + +from contextlib import ExitStack +from mailman.config import config +from mailman.testing.layers import ConfigLayer +from mailman.utilities import uid +from unittest.mock import patch + + + +class TestUID(unittest.TestCase): + layer = ConfigLayer + + def _uid_files(self): + return [filename + for filename in os.listdir(os.path.join(config.VAR_DIR)) + if filename.startswith('.uid') + ] + + def test_context(self): + self.assertNotIn('.uid.foo', self._uid_files()) + uid.UIDFactory('foo').new() + self.assertIn('.uid.foo', self._uid_files()) + + def test_no_context(self): + self.assertNotIn('.uid', self._uid_files()) + uid.UIDFactory().new() + self.assertIn('.uid', self._uid_files()) + + def test_unpredictable_id(self): + with patch('mailman.utilities.uid.layers.is_testing', + return_value=False): + self.assertNotEqual(uid.UIDFactory().new().int, 1) + + def test_uid_record_try_again(self): + called = False + def record_second(ignore): + nonlocal called + if not called: + called = True + raise ValueError + with ExitStack() as resources: + resources.enter_context( + patch('mailman.utilities.uid.layers.is_testing', + return_value=False)) + resources.enter_context( + patch('mailman.utilities.uid.UID.record', record_second)) + mock = resources.enter_context( + patch('mailman.utilities.uid.uuid.uuid4', + return_value=uuid.UUID(int=1))) + uid.UIDFactory().new() + self.assertEqual(mock.call_count, 2) + + def test_unpredictable_token_factory(self): + with patch('mailman.utilities.uid.layers.is_testing', + return_value=False): + self.assertNotEqual(uid.TokenFactory().new(), + '0000000000000000000000000000000000000001') diff --git a/src/mailman/utilities/uid.py b/src/mailman/utilities/uid.py index 9f24cef68..007f7e8f5 100644 --- a/src/mailman/utilities/uid.py +++ b/src/mailman/utilities/uid.py @@ -30,7 +30,6 @@ __all__ = [ import os import time import uuid -import errno import random import hashlib @@ -64,7 +63,7 @@ class _PredictableIDGenerator: # These will get automatically cleaned up by the test # infrastructure. self._uid_file = os.path.join(config.VAR_DIR, '.uid') - if self._context: + if self._context is not None: self._uid_file += '.' + self._context self._lock_file = self._uid_file + '.lock' self._lockobj = Lock(self._lock_file) @@ -90,7 +89,7 @@ class _PredictableIDGenerator: The type of the returned id is intended to be the type that makes sense for the subclass overriding this method. """ - raise NotImplementedError + raise NotImplementedError # pragma: no cover def _next_predictable_id(self): """Generate a predictable id for when Mailman being tested. @@ -98,20 +97,18 @@ class _PredictableIDGenerator: The type of the returned id is intended to be the type that makes sense for the subclass overriding this method. """ - raise NotImplementedError + raise NotImplementedError # pragma: no cover def _next_id(self): with self._lock: try: with open(self._uid_file) as fp: uid = int(fp.read().strip()) - next_uid = uid + 1 + next_uid = uid + 1 # pragma: no branch with open(self._uid_file, 'w') as fp: - fp.write(str(next_uid)) + fp.write(str(next_uid)) # pragma: no branch return uid - except IOError as error: - if error.errno != errno.ENOENT: - raise + except FileNotFoundError: with open(self._uid_file, 'w') as fp: fp.write('2') return 1 |
