123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172 |
- # Copyright 2012 Canonical Ltd.
- # This file is part of lazr.restfulclient.
- #
- # lazr.restfulclient is free software: you can redistribute it and/or
- # modify it under the terms of the GNU Lesser General Public License
- # as published by the Free Software Foundation, version 3 of the
- # License.
- #
- # lazr.restfulclient 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
- # Lesser General Public License for more details.
- #
- # You should have received a copy of the GNU Lesser General Public License
- # along with lazr.restfulclient. If not, see <http://www.gnu.org/licenses/>.
- """Tests for the atomic file cache."""
- __metaclass__ = type
- import shutil
- import sys
- import tempfile
- import unittest
- import httplib2
- from lazr.restfulclient._browser import AtomicFileCache, safename
- PY3 = sys.version_info[0] >= 3
- if PY3:
- binary_type = bytes
- else:
- binary_type = str
- class TestFileCacheInterface(unittest.TestCase):
- """Tests for ``AtomicFileCache``."""
- file_cache_factory = httplib2.FileCache
- unicode_bytes = b"pa\xc9\xaa\xce\xb8\xc9\x99n"
- unicode_text = unicode_bytes.decode("utf-8")
- def setUp(self):
- super(TestFileCacheInterface, self).setUp()
- self.cache_dir = tempfile.mkdtemp()
- def tearDown(self):
- shutil.rmtree(self.cache_dir)
- super(TestFileCacheInterface, self).tearDown()
- def make_file_cache(self):
- """Make a FileCache-like object to be tested."""
- return self.file_cache_factory(self.cache_dir, safename)
- def test_get_non_existent_key(self):
- # get() returns None if the key does not exist.
- cache = self.make_file_cache()
- self.assertIs(None, cache.get("nonexistent"))
- def test_set_key(self):
- # A key set with set() can be got by get().
- cache = self.make_file_cache()
- cache.set("key", b"value")
- self.assertEqual(b"value", cache.get("key"))
- def test_set_twice_overrides(self):
- # Setting a key again overrides the value.
- cache = self.make_file_cache()
- cache.set("key", b"value")
- cache.set("key", b"new-value")
- self.assertEqual(b"new-value", cache.get("key"))
- def test_delete_absent_key(self):
- # Deleting a key that's not there does nothing.
- cache = self.make_file_cache()
- cache.delete("nonexistent")
- self.assertIs(None, cache.get("nonexistent"))
- def test_delete_key(self):
- # A key once set can be deleted. Further attempts to get that key
- # return None.
- cache = self.make_file_cache()
- cache.set("key", b"value")
- cache.delete("key")
- self.assertIs(None, cache.get("key"))
- def test_get_non_string_key(self):
- # get() raises TypeError if asked to get a non-string key.
- cache = self.make_file_cache()
- self.assertRaises(TypeError, cache.get, 42)
- def test_delete_non_string_key(self):
- # delete() raises TypeError if asked to delete a non-string key.
- cache = self.make_file_cache()
- self.assertRaises(TypeError, cache.delete, 42)
- def test_set_non_string_key(self):
- # set() raises TypeError if asked to set a non-string key.
- cache = self.make_file_cache()
- self.assertRaises(TypeError, cache.set, 42, "the answer")
- def test_set_non_string_value(self):
- # set() raises TypeError if asked to set a key to a non-string value.
- # Attempts to retrieve that value return the empty string. This is
- # probably a bug in httplib2.FileCache.
- cache = self.make_file_cache()
- self.assertRaises(TypeError, cache.set, "answer", 42)
- self.assertEqual(b"", cache.get("answer"))
- def test_get_unicode(self):
- # get() can retrieve unicode keys.
- cache = self.make_file_cache()
- self.assertIs(None, cache.get(self.unicode_text))
- def test_set_unicode_keys(self):
- cache = self.make_file_cache()
- cache.set(self.unicode_text, b"value")
- self.assertEqual(b"value", cache.get(self.unicode_text))
- def test_set_unicode_value(self):
- # set() cannot store unicode values. Values must be bytes.
- cache = self.make_file_cache()
- error = TypeError if PY3 else UnicodeEncodeError
- self.assertRaises(error, cache.set, "key", self.unicode_text)
- def test_delete_unicode(self):
- # delete() can remove unicode keys.
- cache = self.make_file_cache()
- cache.set(self.unicode_text, b"value")
- cache.delete(self.unicode_text)
- self.assertIs(None, cache.get(self.unicode_text))
- class TestAtomicFileCache(TestFileCacheInterface):
- """Tests for ``AtomicFileCache``."""
- file_cache_factory = AtomicFileCache
- @staticmethod
- def prefix_safename(x):
- if isinstance(x, binary_type):
- x = x.decode("utf-8")
- return AtomicFileCache.TEMPFILE_PREFIX + x
- def test_set_non_string_value(self):
- # set() raises TypeError if asked to set a key to a non-string value.
- # Attempts to retrieve that value act is if it were never set.
- #
- # Note: This behaviour differs from httplib2.FileCache.
- cache = self.make_file_cache()
- self.assertRaises(TypeError, cache.set, "answer", 42)
- self.assertIs(None, cache.get("answer"))
- # Implementation-specific tests follow.
- def test_bad_safename_get(self):
- safename = self.prefix_safename
- cache = AtomicFileCache(self.cache_dir, safename)
- self.assertRaises(ValueError, cache.get, "key")
- def test_bad_safename_set(self):
- safename = self.prefix_safename
- cache = AtomicFileCache(self.cache_dir, safename)
- self.assertRaises(ValueError, cache.set, "key", b"value")
- def test_bad_safename_delete(self):
- safename = self.prefix_safename
- cache = AtomicFileCache(self.cache_dir, safename)
- self.assertRaises(ValueError, cache.delete, "key")
|