Commits

Lynn Rees committed e18d352 Merge
  • Participants
  • Parent commits 1265945, 78524e5
  • Branches next

Comments (0)

Files changed (40)

 c934d4cc91b3d59b5eae79786dfda88af5648fcf 0.5.0
 5d30e1f6b8ea93c6b40362ed918af36a520cd37e 0.5.1
 5f0d2eda8c3b1525f808f8cba2559a27612934d3 0.5.2
+d0e6b3a98af8bb25c2ad6ba82e673d419ba2aa0f 0.5.3
+d0e6b3a98af8bb25c2ad6ba82e673d419ba2aa0f 0.5.3
+54c6f781259a66efb9d2412b32b68326898bb9b8 0.5.3
+7f0f14ae00fac10221c3d7a713b0853b72bd0722 0.5.4
+ddca2d3b8cc587f5d7a78b328d516d9476db3870 0.5.5
+f265350568afd46636171fdcb14a4cab91caa448 0.5.6
 What's new in 0.5.1
 ===================
 
-- no memoizing of optimized pickling
+- no memoizing of optimized pickling
+
+What's new in 0.5.3
+===================
+
+- optimize pickling, compression pipeline (per Ling Li)
 include CHANGELOG
 include MANIFEST.in
 include README.rst
+include reqs/requires.txt
 recursive-include shove *.py

File reqs/dev_requires.txt

+include test_requires.txt
+tox
+sphinx
+sphinxcontrib.spelling
+Sphinx-PyPI-upload
+Fabric
+hg-github

File reqs/requires.txt

+futures
+stuf==0.9.4

File reqs/test_requires.txt

+futures
 # -*- coding: utf-8 -*-
 '''setup for shove'''
 
+from os import getcwd
+from os.path import join
+
 from setuptools import setup, find_packages
 
 
             if line.startswith('__version__'):
                 return '%s.%s.%s' % eval(line[13:].rstrip())
 
+install_requires = list(l.strip() for l in open(
+    join(getcwd(), 'reqs/requires.txt'),
+))
+
 setup(
     name='shove',
     version=getversion('shove/__init__.py'),
-    description='''Common object storage frontend''',
+    description='Common object storage frontend.',
     long_description=open('README.rst').read(),
     author='L. C. Rees',
     author_email='lcrees@gmail.com',
     license='BSD',
     packages=find_packages(),
     test_suite='shove.tests',
-    install_requires=['futures', 'stuf>=0.8.19'],
+    install_requires=install_requires,
     zip_safe=False,
     keywords='object storage persistence database shelve',
     classifiers=[
     leveldb=shove.stores.leveldbstore:LevelDBStore
     memory=shove.store:MemoryStore
     mongodb=shove.stores.mongodb:MongoDBStore
-    mssql=shove.store.db:DBStore
+    mssql=shove.stores.db:DBStore
     mysql=shove.stores.db:DBStore
     oracle=shove.stores.db:DBStore
-    postgres=shove.store.db:DBStore
+    postgres=shove.stores.db:DBStore
     redis=shove.stores.redisdb:RedisStore
     s3=shove.stores.s3:S3Store
     simple=shove.store:SimpleStore
     firebird=shove.caches.db:DBCache
     memcache=shove.caches.memcached:MemCache
     memlru=shove.cache:MemoryLRUCache
-    memory=shove.caches:MemoryCache
+    memory=shove.cache:MemoryCache
     mssql=shove.caches.db:DBCache
     mysql=shove.caches.db:DBCache
     oracle=shove.caches.db:DBCache

File shove/__init__.py

 
 from shove.core import Shove
 
-__version__ = (0, 5, 2)
+__version__ = (0, 5, 6)
 
 __all__ = ['Shove']

File shove/_compat.py

 # -*- coding: utf-8 -*-
-'''shove compatibility for different python versions'''
-
-try:
-    from urlparse import urlsplit
-    from urllib import quote_plus, unquote_plus
-except ImportError:
-    from urllib.parse import urlsplit, quote_plus, unquote_plus
-try:
-    from urllib import url2pathname
-except ImportError:
-    from urllib.request import url2pathname
-try:
-    import anydbm
-except ImportError:
-    import dbm as anydbm
+'''shove compatibility shim for different python versions.'''
 
 from stuf.six import PY3
-from stuf.six.moves import StringIO  # @UnresolvedImport
+from stuf.base import backport
+
+anydbm = backport('anydbm', 'dbm')
+url2pathname = backport('urllib.url2pathname', 'urllib.request.url2pathname')
+urlsplit = backport('urlparse.urlsplit', 'urllib.parse.urlsplit')
+quote_plus = backport('urllib.quote_plus', 'urllib.parse.quote_plus')
+unquote_plus = backport('urllib.unquote_plus', 'urllib.parse.unquote_plus')
+StringIO = backport('stuf.six.moves.StringIO')
 
 
 def synchronized(func):
     '''
     Decorator to lock and unlock a method (Phillip J. Eby).
 
-    @param func Method to decorate
+    :argument func: method to decorate
     '''
     def wrapper(self, *__args, **__kw):
         self._lock.acquire()

File shove/base.py

 # -*- coding: utf-8 -*-
 '''shove core.'''
 
+from functools import partial
 from os.path import exists, join
 from os import listdir, remove, makedirs
 from zlib import compress, decompress, error
 
-from stuf.utils import ld, optimize
-from stuf.six import HIGHEST_PROTOCOL
+from stuf.six import pickle
+from stuf.utils import loads, optimize
 
 from shove._compat import url2pathname, quote_plus, unquote_plus
 
 
 class Base(object):
 
-    '''
-    Base.
-    '''
+    '''Base for shove.'''
 
     def __init__(self, engine, **kw):
         # keyword compress True, False, or an integer compression level (1-9)
         self._compress = kw.get('compress', False)
         # pickle protocol
-        self._protocol = kw.get('protocol', HIGHEST_PROTOCOL)
+        protocol = kw.get('protocol', pickle.HIGHEST_PROTOCOL)
+        if kw.get('optimize', True):
+            self._optimizer = partial(optimize, p=protocol)
+        else:
+            self._optimizer = partial(pickle.dumps, protocol=protocol)
 
     def __contains__(self, key):
         try:
             return True
 
     def dumps(self, value):
-        '''
-        Optionally serializes and compresses an object.
-        '''
+        '''Optionally serializes and compresses object `value`.'''
         # serialize anything but ASCII strings
-        value = optimize(value)
+        value = self._optimizer(value)
         compression = self._compress
         if compression:
-            value = compress(value, 9 if compression else compression)
+            value = compress(value, 9 if compression is True else compression)
         return value
 
     def loads(self, value):
-        '''
-        Deserializes and optionally decompresses an object.
-        '''
+        '''Deserializes and optionally decompresses object `value`.'''
         if self._compress:
             try:
                 value = decompress(value)
             except error:
                 pass
-        return ld(value)
+        return loads(value)
 
 
 class Mapping(Base):
 
-    '''
-    Base mapping.
-    '''
+    '''Base mapping for shove.'''
 
     def __getitem__(self, key):
         try:
             return self._store[key]
-        except:
+        except KeyError:
             raise KeyError(key)
 
     def __setitem__(self, key, value):
     def __delitem__(self, key):
         try:
             del self._store[key]
-        except:
+        except KeyError:
             raise KeyError(key)
 
     def __iter__(self):
     def __len__(self):
         return len(self._store)
 
-    def dumps(self, value):
-        '''
-        Optionally serializes and compresses an object.
-        '''
-        # serialize anything but ASCII strings
-        value = optimize(value)
-        compression = self._compress
-        if compression:
-            value = compress(value, 9 if compression else compression)
-        return value
-
-    def loads(self, value):
-        '''
-        Deserializes and optionally decompresses an object.
-        '''
-        if self._compress:
-            try:
-                value = decompress(value)
-            except error:
-                pass
-        return ld(value)
-
 
 class FileBase(Base):
 
-    '''
-    Base for file based storage.
-    '''
+    '''Base for file based storage.'''
 
     def __init__(self, engine, **kw):
         super(FileBase, self).__init__(engine, **kw)
             makedirs(self._dir)
         except OSError:
             raise EnvironmentError(
-                'Cache directory "{0}" does not exist and could not be '
+                'cache directory "{0}" does not exist and could not be '
                 'created'.format(self._dir)
             )
 

File shove/cache.py

 # -*- coding: utf-8 -*-
-'''
-shove cache core
-'''
+'''shove cache core.'''
 
 import random
 from time import time
 from shove._compat import synchronized
 from shove.base import Mapping, FileBase
 
-__all__ = [
-    'FileCache', 'FileLRUCache', 'MemoryCache', 'MemoryLRUCache',
-    'SimpleLRUCache', 'SimpleCache',
-]
+__all__ = (
+    'FileCache FileLRUCache MemoryCache SimpleCache MemoryLRUCache'
+    'SimpleLRUCache'
+).split()
 
 
 class BaseCache(object):
         return value
 
     def __setitem__(self, key, value):
-        # cull values if over max number of entries
-        if len(self) >= self._max_entries:
-            self._cull()
         # set expiration time and value
         exp = time() + self.timeout
         super(BaseCache, self).__setitem__(key, (exp, value))
+        # cull values if over max number of entries
+        if len(self) > self._max_entries:
+            self._cull()
 
     def _cull(self):
-        # remove items in cache to make room
-        maxcull = self._maxcull
-        # cull number of items allowed (set by self._maxcull)
-        for num, key in enumerate(self):
-            # remove only maximum # of items allowed by maxcull
-            if num <= maxcull:
-                # remove items if expired
-                try:
-                    self[key]
-                except KeyError:
-                    num += 1
-            else:
-                break
-        choice = random.choice
-        keys = list(self)
-        max_entries = self._max_entries
-        # remove any additional items up to max # of items allowed by maxcull
-        while len(self) >= max_entries and num <= maxcull:
-            # cull remainder of allowed quota at random
-            del self[choice(keys)]
-            num += 1
+        # cull remainder of allowed quota at random
+        for key in random.sample(list(self), len(self) - self._max_entries):
+            del self[key]
 
 
 class SimpleCache(BaseCache, Mapping):

File shove/caches/db.py

 
 class DBCache(Base):
 
-    '''
-    Database cache backend.
-    '''
+    '''Relational database-based cache frontend.'''
 
     def __init__(self, engine, **kw):
         super(DBCache, self).__init__(engine, **kw)

File shove/caches/memcached.py

 
 class MemCache(Base):
 
-    '''Memcached cache backend'''
+    '''Memcached-based cache frontend.'''
 
     def __init__(self, engine, **kw):
         super(MemCache, self).__init__(engine, **kw)

File shove/caches/redisdb.py

 
 class RedisCache(Base):
 
-    '''Redis cache backend'''
+    '''Redis-based cache backend'''
 
     init = 'redis://'
 

File shove/core.py

 from operator import methodcaller
 from collections import MutableMapping
 
-from stuf.iterable import exhaustcall
+from stuf import exhaustmap
 from concurrent.futures import ThreadPoolExecutor
 
 from shove._imports import cache_backend, store_backend
 
-__all__ = ('Shove', 'MultiShove')
+__all__ = 'Shove MultiShove'.split()
 
 
 class Shove(MutableMapping):
 
-    '''
-    Common object frontend class.
-    '''
+    '''Common object frontend class.'''
 
     def __init__(self, store='simple://', cache='simple://', **kw):
         super(Shove, self).__init__()
         self._sync = kw.get('sync', 2)
 
     def __getitem__(self, key):
-        '''
-        Gets a item from shove.
-        '''
         try:
             return self._cache[key]
         except KeyError:
             return value
 
     def __setitem__(self, key, value):
-        '''
-        Sets an item in shove.
-        '''
         self._cache[key] = self._buffer[key] = value
         # when buffer reaches self._limit, write buffer to store
         if len(self._buffer) >= self._sync:
             self.sync()
 
     def __delitem__(self, key):
-        '''
-        Deletes an item from shove.
-        '''
         self.sync()
         try:
             del self._cache[key]
         return self._store.__iter__()
 
     def close(self):
-        '''
-        Finalizes and closes shove.
-        '''
+        '''Finalizes and closes shove.'''
         # if close has been called, pass
         if self._store is not None:
             try:
         self._store = self._cache = self._buffer = None
 
     def sync(self):
-        '''
-        Writes buffer to store.
-        '''
+        '''Writes buffer to store.'''
         self._store.update(self._buffer)
         self._buffer.clear()
 
 
 class MultiShove(MutableMapping):
 
-    '''
-    Common frontend to multiple object stores.
-    '''
+    '''Common frontend to multiple object stores.'''
 
     def __init__(self, *stores, **kw):
         # init superclass with first store
         self._sync = kw.get('sync', 2)
 
     def __getitem__(self, key):
-        '''
-        Get a item from shove.
-        '''
         try:
             return self._cache[key]
         except KeyError:
             return value
 
     def __setitem__(self, key, value):
-        '''
-        Sets an item in shove.
-        '''
         self._cache[key] = self._buffer[key] = value
         # when the buffer reaches self._limit, writes the buffer to the store
         if len(self._buffer) >= self._sync:
             self.sync()
 
     def __delitem__(self, key):
-        '''
-        Deletes an item from multiple stores.
-        '''
         try:
             self.sync()
         except AttributeError:
             pass
-        exhaustcall(methodcaller('__delitem__', key), self._stores)
+        exhaustmap(methodcaller('__delitem__', key), self._stores)
         try:
             del self._cache[key]
         except KeyError:
         return self._stores[0].__iter__()
 
     def close(self):
-        '''
-        Finalizes and closes shove stores.
-        '''
+        '''Finalizes and closes shove stores.'''
         # if close has been called, pass
         stores = self._stores
         if self._stores is not None:
         self._cache = self._buffer = self._stores = None
 
     def sync(self):
-        '''
-        Writes buffer to stores.
-        '''
-        exhaustcall(methodcaller('update', self._buffer), self._stores)
+        '''Writes buffer to stores.'''
+        exhaustmap(methodcaller('update', self._buffer), self._stores)
         self._buffer.clear()
 
 
 class ThreadShove(MultiShove):
 
-    '''
-    Common frontend that syncs multiple object stores with multiple threads.
-    '''
+    '''Common frontend that syncs multiple object stores with threads.'''
 
     def __init__(self, *stores, **kw):
         # init superclass with first store
             method = partial(
                 executor.submit, methodcaller('__delitem__', key)
             )
-            exhaustcall(method, self._stores)
+            exhaustmap(method, self._stores)
         try:
             del self._cache[key]
         except KeyError:
             pass
 
     def sync(self):
-        '''
-        Writes buffer to store.
-        '''
+        '''Writes buffer to store.'''
         with ThreadPoolExecutor(max_workers=self._maxworkers) as executor:
             method = partial(
                 executor.submit, methodcaller('update', self._buffer),
             )
-            exhaustcall(method, self._stores)
+            exhaustmap(method, self._stores)
         self._buffer.clear()

File shove/store.py

 from shove.base import Mapping, FileBase
 from shove._compat import anydbm, synchronized, url2pathname
 
-__all__ = ('DBMStore', 'FileStore', 'MemoryStore', 'SimpleStore')
+__all__ = 'DBMStore FileStore MemoryStore SimpleStore'.split()
 
 
 class BaseStore(Mapping, MutableMapping):
     '''Base store.'''
 
     def close(self):
-        '''
-        Closes internal store and clears object references.
-        '''
+        '''Closes internal store and clears object references.'''
         try:
             self._store.close()
         except AttributeError:
 
 class ClientStore(BaseStore):
 
-    '''
-    Base store where updates must be committed to disk.
-    '''
+    '''Base store where updates must be committed to disk.'''
 
     def __init__(self, engine, **kw):
         super(ClientStore, self).__init__(engine, **kw)
 
 class SyncStore(ClientStore):
 
-    '''
-    Base store where updates have to be synced to disk.
-    '''
+    '''Base store where updates have to be synced to disk.'''
 
     def __setitem__(self, key, value):
         super(SyncStore, self).__setitem__(key, value)
     init = 'file://'
 
     def clear(self):
+        '''Clear all objects from store.'''
         shutil.rmtree(self._dir)
         self._createdir()

File shove/stores/bsdb.py

 
 class BSDBStore(SyncStore):
 
-    '''
-    Berkeley Source Database store.
-    '''
+    '''Berkeley Source Database-based object storage frontend.'''
 
     init = 'bsddb://'
 

File shove/stores/cassandra.py

 
 class CassandraStore(SimpleStore):
 
-    '''Cassandra based store'''
+    '''Cassandra based storage frontend.'''
 
     init = 'cassandra://'
 
                 pycassa.ConnectionPool(keyspace, [spliturl.netloc]),
                 column_family,
             )
+        except pycassa.NotFoundException:
+            from pycassa.system_manager import SystemManager  # @UnresolvedImport @IgnorePep8
+            system_manager = SystemManager(spliturl[1])
+            system_manager.create_column_family(keyspace, column_family)
+            self._store = pycassa.ColumnFamily(
+                pycassa.ConnectionPool(keyspace, [spliturl.netloc]),
+                column_family,
+            )
 
     def __getitem__(self, key):
         try:

File shove/stores/db.py

 # -*- coding: utf-8 -*-
 '''
-Database object store.
+Relational database object store.
 
-The shove URI used for database object stores is the format used by
+The shove URI used for relational database object stores is the format used by
 SQLAlchemy:
 
 <driver>://<username>:<password>@<host>:<port>/<database>
 
 class DBStore(BaseStore):
 
-    '''
-    Database cache backend.
-    '''
+    '''Relational database-based object storage frontend.'''
 
     def __init__(self, engine, **kw):
         super(DBStore, self).__init__(engine, **kw)

File shove/stores/durusdb.py

 
 class DurusStore(SyncStore):
 
-    '''
-    Durus object database frontend.
-    '''
+    '''Durus-based object storage frontend.'''
 
     init = 'durus://'
 

File shove/stores/ftp.py

 # -*- coding: utf-8 -*-
 '''
-FTP-accessed stores
+FTP-accessed stores.
 
 shove's URI for FTP accessed stores follows the standard form for FTP URLs
 defined in RFC-1738:
 
 class FTPStore(BaseStore):
 
+    '''FTP-based object storage frontend.'''
+
     def __init__(self, engine, **kw):
         super(FTPStore, self).__init__(engine, **kw)
         user = kw.get('user', 'anonymous')

File shove/stores/gitstore.py

 # -*- coding: utf-8 -*-
 '''
-git-based object store.
+git versioned object store.
 
 shove's URI for git-based stores follows the form:
 
 
 class GitStore(FileStore):
 
+    '''Git versioned filesystem based object storage frontend.'''
+
     init = 'git://'
 
     def __init__(self, engine, **kw):

File shove/stores/hdf5.py

 # -*- coding: utf-8 -*-
 '''
-HDF5 Database Store.
+HDF5 database store.
 
 shove's URI for HDF5 stores follows the form:
 
 
 class HDF5Store(ClientStore):
 
-    '''LevelDB based store'''
+    '''HDF5-based object storage frontend.'''
 
     init = 'hdf5://'
 

File shove/stores/hgstore.py

 # -*- coding: utf-8 -*-
 '''
-Mercurial-based object store.
+Mercurial versioned object store.
 
 shove's URI for Mercurial-based stores follows the form:
 
 
 class HgStore(FileStore):
 
+    '''Mercurial versioned filesystem based object storage frontend.'''
+
     init = 'hg://'
 
     def __init__(self, engine, **kw):

File shove/stores/leveldbstore.py

 # -*- coding: utf-8 -*-
 '''
-LevelDB Database Store.
+LevelDB database store.
 
 shove's URI for LevelDB stores follows the form:
 
 class LevelDBStore(ClientStore):
 
     '''
-    LevelDB based store.
+    LevelDB-based object storage frontend.
     '''
 
     init = 'leveldb://'

File shove/stores/mongodb.py

 # -*- coding: utf-8 -*-
 '''
-MongoDB Database Store.
+MongoDB database store.
 
 shove's URI for MongoDB stores follows the form:
 
 
 class MongoDBStore(SimpleStore):
 
-    '''
-    MongoDB based store.
-    '''
+    '''MongoDB-based object storage frontend.'''
 
     init = 'mongodb://'
 

File shove/stores/redisdb.py

 
 class RedisStore(BaseStore):
 
-    '''
-    Redis based store.
-    '''
+    '''Redis-based object storage frontend.'''
 
     init = 'redis://'
 

File shove/stores/s3.py

 
 class S3Store(BaseStore):
 
-    '''
-    S3 store.
-    '''
+    '''S3-based object storage frontend.'''
 
     def __init__(self, engine=None, **kw):
         super(S3Store, self).__init__(engine, **kw)
             raise KeyError(key)
 
     def keys(self):
-        '''
-        Returns a list of keys in the store.
-        '''
+        '''List of keys in the store.'''
         return list(i[0] for i in self.items())
 
     def items(self):
-        '''
-        Returns a list of items from the store.
-        '''
+        '''List of items in the store.'''
         if self._updated or self._keys is None:
             self._keys = self._store.get_all_keys()
         return list((native(k.key), k) for k in self._keys)
 
     def iteritems(self):
-        '''
-        Lazily returns items from the store.
-        '''
+        '''Lazily returns items from the store.'''
         for k in self.items():
             yield (k.key, k)

File shove/stores/zodb.py

 
 class ZODBStore(SyncStore):
 
-    '''ZODB front end.'''
+    '''ZODB-based object storage frontend.'''
 
     init = 'zodb://'
 
         self.sync = transaction.commit
 
     def close(self):
-        '''
-        Closes all open storage and connections.
-        '''
+        '''Closes all open storage and connections.'''
         self.sync()
         super(ZODBStore, self).close()
         self._connection.close()

File shove/tests/__init__.py

-# -*- coding: utf-8 -*-
-'''shove tests'''

File shove/tests/mixins.py

-# -*- coding: utf-8 -*-
-'''shove test mixins'''
-
-
-class Spawn(object):
-
-    shell = False
-
-    @staticmethod
-    def setUpModule():
-        import os
-        from tempfile import mkdtemp
-        TMP = mkdtemp()
-        os.environ['TEST_DIR'] = TMP
-        os.chdir(TMP)
-
-    @staticmethod
-    def tearDownModule():
-        import os
-        from shutil import rmtree
-        rmtree(os.environ['TEST_DIR'])
-        del os.environ['TEST_DIR']
-
-    @classmethod
-    def setUpClass(cls):
-        from subprocess32 import Popen  # @UnresolvedImport
-        cls.process = Popen(
-            cls.cmd, stdout=open('/dev/null', 'w'), shell=cls.shell
-        )
-
-    @classmethod
-    def tearDownClass(cls):
-        cls.process.kill()

File shove/tests/test_cache.py

-# -*- coding: utf-8 -*-
-'''shove cache tests'''
-
-from stuf.six import PY3, unittest
-from shove.tests.mixins import Spawn
-
-setUpModule = Spawn.setUpModule
-tearDownModule = Spawn.tearDownModule
-
-
-class NoTimeout(object):
-
-    def setUp(self):
-        self.cache = self._makeone(self.initstring)
-
-    def tearDown(self):
-        self.cache = None
-
-    def test_getitem(self):
-        self.cache['test'] = 'test'
-        self.assertEqual(self.cache['test'], 'test')
-
-    def test_setitem(self):
-        self.cache['test'] = 'test'
-        self.assertEqual(self.cache['test'], 'test')
-
-    def test_delitem(self):
-        self.cache['test'] = 'test'
-        del self.cache['test']
-        self.assertEqual('test' in self.cache, False)
-
-
-class Cache(NoTimeout):
-
-    def test_timeout(self):
-        import time
-        cache = self._makeone(self.initstring, timeout=1)
-        cache['test'] = 'test'
-        time.sleep(3)
-        def tmp(): #@IgnorePep8
-            cache['test']
-        self.assertRaises(KeyError, tmp)
-
-
-class CacheCull(Cache):
-
-    def test_cull(self):
-        cache = self._makeone(self.initstring, max_entries=1)
-        cache['test'] = 'test'
-        cache['test2'] = 'test'
-        cache['test2'] = 'test'
-        self.assertEquals(len(cache), 1)
-
-
-class TestSimpleCache(CacheCull, unittest.TestCase):
-
-    initstring = 'simple://'
-
-    @property
-    def _makeone(self):
-        from shove.cache import SimpleCache
-        return SimpleCache
-
-
-class TestSimpleLRUCache(NoTimeout, unittest.TestCase):
-
-    initstring = 'simplelru://'
-
-    @property
-    def _makeone(self):
-        from shove.cache import SimpleLRUCache
-        return SimpleLRUCache
-
-
-class TestMemoryCache(CacheCull, unittest.TestCase):
-
-    initstring = 'memory://'
-
-    @property
-    def _makeone(self):
-        from shove.cache import MemoryCache
-        return MemoryCache
-
-
-class TestMemoryLRUCache(NoTimeout, unittest.TestCase):
-
-    initstring = 'memlru://'
-
-    @property
-    def _makeone(self):
-        from shove.cache import MemoryLRUCache
-        return MemoryLRUCache
-
-
-class TestFileCache(CacheCull, unittest.TestCase):
-
-    initstring = 'file://test'
-
-    @property
-    def _makeone(self):
-        from shove.cache import FileCache
-        return FileCache
-
-    def tearDown(self):
-        import shutil
-        self.cache = None
-        shutil.rmtree('test')
-
-
-class TestFileLRUCache(NoTimeout, unittest.TestCase):
-
-    initstring = 'filelru://test2'
-
-    @property
-    def _makeone(self):
-        from shove.cache import FileLRUCache
-        return FileLRUCache
-
-    def tearDown(self):
-        import shutil
-        self.cache = None
-        shutil.rmtree('test2')
-
-
-class TestDBCache(CacheCull, unittest.TestCase):
-
-    initstring = 'sqlite:///'
-
-    @property
-    def _makeone(self):
-        from shove.caches.db import DBCache
-        return DBCache
-
-
-if not PY3:
-    class TestMemcache(Cache, Spawn, unittest.TestCase):
-
-        initstring = 'memcache://localhost:11211'
-        cmd = ['memcached']
-
-        @property
-        def _makeone(self):
-            from shove.caches.memcached import MemCache
-            return MemCache
-
-    class TestRedisCache(Cache, Spawn, unittest.TestCase):
-
-        initstring = 'redis://localhost:6379/0'
-        cmd = ['redis-server']
-
-        @property
-        def _makeone(self):
-            from shove.caches.redisdb import RedisCache
-            return RedisCache
-
-
-if __name__ == '__main__':
-    unittest.main()

File shove/tests/test_multishove.py

-# -*- coding: utf-8 -*-
-'''shove multishove tests'''
-
-from stuf.six import unittest
-
-
-def setUpModule():
-    import os
-    from tempfile import mkdtemp
-    TMP = mkdtemp()
-    os.chdir(TMP)
-
-
-class Multi(object):
-
-    def test__getitem__(self):
-        self.store['max'] = 3
-        self.store.sync()
-        self.assertEqual(self.store['max'], 3)
-
-    def test__setitem__(self):
-        self.store['max'] = 3
-        self.store.sync()
-        self.assertEqual(self.store['max'], 3)
-
-    def test__delitem__(self):
-        self.store['max'] = 3
-        self.store.sync()
-        del self.store['max']
-        self.store.sync()
-        self.assertEqual('max' in self.store, False)
-
-    def test_get(self):
-        self.store['max'] = 3
-        self.store.sync()
-        self.assertEqual(self.store.get('min'), None)
-
-    def test__cmp__(self):
-        from shove.core import MultiShove
-        tstore = MultiShove()
-        self.store['max'] = 3
-        tstore['max'] = 3
-        self.store.sync()
-        tstore.sync()
-        self.assertEqual(self.store, tstore)
-
-    def test__len__(self):
-        self.store['max'] = 3
-        self.store['min'] = 6
-        self.store['pow'] = 7
-        self.store.sync()
-        self.assertEqual(len(self.store), 3)
-
-    def test_clear(self):
-        self.store['max'] = 3
-        self.store['min'] = 6
-        self.store['pow'] = 7
-        self.store.clear()
-        self.assertEqual(len(self.store), 0)
-
-    def test_items(self):
-        self.store['max'] = 3
-        self.store['min'] = 6
-        self.store['pow'] = 7
-        self.store.sync()
-        slist = list(self.store.items())
-        self.assertEqual(('min', 6) in slist, True)
-
-    def test_keys(self):
-        self.store['max'] = 3
-        self.store['min'] = 6
-        self.store['pow'] = 7
-        self.store.sync()
-        slist = list(self.store.keys())
-        self.assertEqual('min' in slist, True)
-
-    def test_values(self):
-        self.store['max'] = 3
-        self.store['min'] = 6
-        self.store['pow'] = 7
-        self.store.sync()
-        slist = list(self.store.values())
-        self.assertEqual(6 in slist, True)
-
-    def test_pop(self):
-        self.store['max'] = 3
-        self.store['min'] = 6
-        self.store.sync()
-        item = self.store.pop('min')
-        self.store.sync()
-        self.assertEqual(item, 6)
-
-    def test_popitem(self):
-        self.store['max'] = 3
-        self.store['min'] = 6
-        self.store['pow'] = 7
-        self.store.sync()
-        item = self.store.popitem()
-        self.store.sync()
-        self.assertEqual(len(item) + len(self.store), 4)
-
-    def test_setdefault(self):
-        self.store['max'] = 3
-        self.store['min'] = 6
-        self.store['powl'] = 7
-        self.store.sync()
-        self.store.setdefault('pow', 8)
-        self.store.sync()
-        self.assertEqual(self.store['pow'], 8)
-
-    def test_update(self):
-        from shove.core import MultiShove
-        tstore = MultiShove()
-        tstore['max'] = 3
-        tstore['min'] = 6
-        tstore['pow'] = 7
-        self.store['max'] = 2
-        self.store['min'] = 3
-        self.store['pow'] = 7
-        self.store.update(tstore)
-        self.store.sync()
-        self.assertEqual(self.store['min'], 6)
-
-
-class TestMultiShove(Multi, unittest.TestCase):
-
-    stores = (
-        'simple://', 'dbm://one.dbm', 'memory://', 'file://two', 'sqlite://',
-    )
-
-    def setUp(self):
-        from shove.core import MultiShove
-        self.store = MultiShove(*self.stores, sync=0)
-
-    def tearDown(self):
-        import os
-        import shutil
-        self.store.close()
-        shutil.rmtree('two')
-        try:
-            os.remove('one.dbm')
-        except OSError:
-            os.remove('one.dbm.db')
-
-
-class TestThreadShove(unittest.TestCase):
-
-    stores = (
-        'simple://', 'memory://', 'file://six', 'sqlite://',
-    )
-
-    def setUp(self):
-        from shove.core import ThreadShove
-        self.store = ThreadShove(*self.stores, max_workers=2, sync=0)
-
-    def tearDown(self):
-        import shutil
-        self.store.close()
-        shutil.rmtree('six')
-
-
-if __name__ == '__main__':
-    unittest.main()

File shove/tests/test_store.py

-# -*- coding: utf-8 -*-
-'''shove store tests'''
-
-from stuf.six import PY3, unittest, keys, values, items
-from shove.tests.mixins import Spawn
-
-setUpModule = Spawn.setUpModule
-tearDownModule = Spawn.tearDownModule
-
-
-class Store(object):
-
-    def setUp(self):
-        from shove import Shove
-        self.store = Shove(self.initstring, compress=True, sync=0)
-
-    def tearDown(self):
-        self.store.close()
-
-    def test__getitem__(self):
-        self.store['max'] = 3
-        self.store.sync()
-        self.assertEqual(self.store['max'], 3)
-
-    def test__setitem__(self):
-        self.store['max'] = 3
-        self.store['d'] = {'A': 1}, {'A': 1}
-        self.store['d'] = {'AA': 1}, {'A': 1}
-        self.store['d'] = {'AA': 1}, {'AA': 1}
-        self.store.sync()
-        self.assertEqual(self.store['max'], 3)
-
-    def test__delitem__(self):
-        self.store['max'] = 3
-        self.store.sync()
-        del self.store['max']
-        self.store.sync()
-        self.assertEqual('max' in self.store, False)
-
-    def test_get(self):
-        self.store['max'] = 3
-        self.store.sync()
-        self.assertEqual(self.store.get('min'), None)
-
-    def test__cmp__(self):
-        from shove import Shove
-        tstore = Shove()
-        self.store['max'] = 3
-        self.store.sync()
-        tstore['max'] = 3
-        self.assertEqual(self.store, tstore)
-
-    def test__len__(self):
-        self.store['max'] = 3
-        self.store['min'] = 6
-        self.store.sync()
-        self.assertEqual(len(self.store), 2)
-
-    def test_items(self):
-        self.store['max'] = 3
-        self.store['min'] = 6
-        self.store['pow'] = 7
-        self.store.sync()
-        slist = list(items(self.store))
-        self.assertEqual(('min', 6) in slist, True)
-
-    def test_keys(self):
-        self.store['max'] = 3
-        self.store['min'] = 6
-        self.store['pow'] = 7
-        self.store.sync()
-        slist = list(keys(self.store))
-        self.assertEqual('min' in slist, True)
-
-    def test_values(self):
-        self.store['max'] = 3
-        self.store['min'] = 6
-        self.store['pow'] = 7
-        self.store.sync()
-        slist = list(values(self.store))
-        self.assertEqual(6 in slist, True)
-
-    def test_pop(self):
-        self.store['max'] = 3
-        self.store['min'] = 6
-        self.store.sync()
-        item = self.store.pop('min')
-        self.store.sync()
-        self.assertEqual(item, 6)
-
-    def test_setdefault(self):
-        self.store['max'] = 3
-        self.store['min'] = 6
-        self.store.sync()
-        self.assertEqual(self.store.setdefault('pow', 8), 8)
-        self.store.sync()
-        self.assertEqual(self.store['pow'], 8)
-
-    def test_update(self):
-        from shove import Shove
-        tstore = Shove()
-        tstore['max'] = 3
-        tstore['min'] = 6
-        tstore['pow'] = 7
-        self.store['max'] = 2
-        self.store['min'] = 3
-        self.store['pow'] = 7
-        self.store.update(tstore)
-        self.store.sync()
-        self.assertEqual(self.store['min'], 6)
-
-    def test_clear(self):
-        self.store['max'] = 3
-        self.store['min'] = 6
-        self.store['pow'] = 7
-        self.store.sync()
-        self.store.clear()
-        self.store.sync()
-        self.assertEqual(len(self.store), 0)
-
-    def test_popitem(self):
-        self.store['max'] = 3
-        self.store['min'] = 6
-        self.store['pow'] = 7
-        self.store.sync()
-        item = self.store.popitem()
-        self.store.sync()
-        self.assertEqual(len(item) + len(self.store), 4)
-
-    def test_close(self):
-        self.store.close()
-        self.assertEqual(self.store._store, None)
-        self.assertEqual(self.store._buffer, None)
-        self.assertEqual(self.store._cache, None)
-
-
-class TestSimpleStore(Store, unittest.TestCase):
-
-    initstring = 'simple://'
-
-
-class TestMemoryStore(Store, unittest.TestCase):
-
-    initstring = 'memory://'
-
-
-class TestFileStore(Store, unittest.TestCase):
-
-    initstring = 'file://test'
-
-    def tearDown(self):
-        import shutil
-        self.store.close()
-        shutil.rmtree('test')
-
-
-class TestHgStore(Store, unittest.TestCase):
-
-    initstring = 'hg://test3'
-
-    def tearDown(self):
-        import shutil
-        self.store.close()
-        shutil.rmtree('test3')
-
-
-class TestGitStore(Store, unittest.TestCase):
-
-    initstring = 'git://test4'
-
-    def tearDown(self):
-        import shutil
-        self.store.close()
-        shutil.rmtree('test4')
-
-
-class TestDBMStore(Store, unittest.TestCase):
-
-    initstring = 'dbm://test.dbm'
-
-    def tearDown(self):
-        import os
-        self.store.close()
-        try:
-            os.remove('test.dbm')
-        except OSError:
-            os.remove('test.dbm.db')
-
-
-class TestDBStore(Store, unittest.TestCase):
-
-    initstring = 'sqlite://'
-
-
-class TestMongoDBStore(Store, Spawn, unittest.TestCase):
-
-    initstring = 'mongodb://127.0.0.1:27017/shove/shove'
-    cmd = [
-        'mongod', '--dbpath', './mongo/', '--nohttpinterface',
-        '--nounixsocket',
-    ]
-
-    @classmethod
-    def setUpClass(cls):
-        import os
-        from fabric.api import local
-        os.mkdir('mongo')
-        local('touch ./mongo/mongo.log')
-        super(TestMongoDBStore, cls).setUpClass()
-        import time
-        time.sleep(10.0)
-
-    def tearDown(self):
-        self.store.clear()
-
-    def test_close(self):
-        pass
-
-
-@unittest.skip('reason')
-class TestFTPStore(Store, unittest.TestCase):
-
-    initstring = 'ftp://127.0.0.1/'
-
-    def setUp(self):
-        from shove import Shove
-        self.store = Shove(self.initstring, compress=True)
-
-    def tearDown(self):
-        self.store.clear()
-        self.store.close()
-
-
-@unittest.skip('reason')
-class TestS3Store(Store, unittest.TestCase):
-
-    initstring = 's3 test string here'
-
-    def tearDown(self):
-        self.store.clear()
-        self.store.close()
-
-
-if not PY3:
-    class TestZODBStore(Store, unittest.TestCase):
-
-        initstring = 'zodb://test.db'
-
-        def tearDown(self):
-            self.store.close()
-            import os
-            os.remove('test.db')
-            os.remove('test.db.index')
-            os.remove('test.db.tmp')
-            os.remove('test.db.lock')
-
-    class TestDurusStore(Store, unittest.TestCase):
-
-        initstring = 'durus://test.durus'
-
-        def tearDown(self):
-            import os
-            self.store.close()
-            os.remove('test.durus')
-
-    class TestRedisStore(Store, Spawn, unittest.TestCase):
-
-        initstring = 'redis://localhost:6379/0'
-        cmd = ['redis-server']
-
-        def tearDown(self):
-            if self.store._store is not None:
-                self.store.clear()
-                self.store.close()
-
-    @unittest.skip('reason')
-    class TestBSDBStore(Store, unittest.TestCase):
-
-        initstring = 'bsddb://test.db'
-
-        def tearDown(self):
-            import os
-            self.store.close()
-            os.remove('test.db')
-
-    class TestCassandraStore(Store, Spawn, unittest.TestCase):
-
-        cmd = ['cassandra', '-f']
-
-        @classmethod
-        def setUpClass(cls):
-            super(TestCassandraStore, cls).setUpClass()
-            import time
-            time.sleep(5.0)
-
-        def setUp(self):
-            from shove import Shove
-            from pycassa.system_manager import SystemManager  # @UnresolvedImport @IgnorePep8
-            system_manager = SystemManager('localhost:9160')
-            try:
-                system_manager.create_column_family('Murk', 'shove')
-            except:
-                pass
-            self.store = Shove('cassandra://localhost:9160/Murk/shove')
-
-        def tearDown(self):
-            if self.store._store is not None:
-                self.store.clear()
-                self.store.close()
-            from pycassa.system_manager import SystemManager  # @UnresolvedImport @IgnorePep8
-            system_manager = SystemManager('localhost:9160')
-            system_manager.drop_column_family('Murk', 'shove')
-
-        @classmethod
-        def tearDownClass(cls):
-            from fabric.api import local
-            local('killall java')
-
-    class TestHDF5Store(Store, unittest.TestCase):
-
-        initstring = 'hdf5://test.hdf5/test'
-
-        def setUp(self):
-            from shove import Shove
-            self.store = Shove()
-
-        def tearDown(self):
-            import os
-            self.store.close()
-            try:
-                os.remove('test.hdf5')
-            except OSError:
-                pass
-
-    @unittest.skip('reason')
-    class TestLevelDBStore(unittest.TestCase):
-
-        initstring = 'leveldb://test'
-
-        def tearDown(self):
-            import shutil
-            shutil.rmtree('test')
-
-
-if __name__ == '__main__':
-    unittest.main()

File tests/__init__.py

+# -*- coding: utf-8 -*-
+'''shove tests'''

File tests/mixins.py

+# -*- coding: utf-8 -*-
+'''shove test mixins'''
+
+
+class Spawn(object):
+
+    shell = False
+
+    @staticmethod
+    def setUpModule():
+        import os
+        from tempfile import mkdtemp
+        TMP = mkdtemp()
+        os.environ['TEST_DIR'] = TMP
+        os.chdir(TMP)
+
+    @staticmethod
+    def tearDownModule():
+        import os
+        from shutil import rmtree
+        rmtree(os.environ['TEST_DIR'])
+        del os.environ['TEST_DIR']
+
+    @classmethod
+    def setUpClass(cls):
+        from subprocess32 import Popen  # @UnresolvedImport
+        cls.process = Popen(
+            cls.cmd, stdout=open('/dev/null', 'w'), shell=cls.shell
+        )
+        import time
+        time.sleep(15.0)
+
+    @classmethod
+    def tearDownClass(cls):
+        cls.process.kill()

File tests/test_cache.py

+# -*- coding: utf-8 -*-
+'''shove cache tests'''
+
+from stuf.six import PY3, unittest
+
+from tests.mixins import Spawn
+
+
+setUpModule = Spawn.setUpModule
+tearDownModule = Spawn.tearDownModule
+
+
+class NoTimeout(object):
+
+    def setUp(self):
+        from shove._imports import cache_backend
+        self.cache = cache_backend(self.initstring)
+
+    def tearDown(self):
+        self.cache = None
+
+    def test_getitem(self):
+        self.cache['test'] = 'test'
+        self.assertEqual(self.cache['test'], 'test')
+
+    def test_setitem(self):
+        self.cache['test'] = 'test'
+        self.assertEqual(self.cache['test'], 'test')
+
+    def test_delitem(self):
+        self.cache['test'] = 'test'
+        del self.cache['test']
+        self.assertEqual('test' in self.cache, False)
+
+
+class Cache(NoTimeout):
+
+    def test_timeout(self):
+        import time
+        from shove._imports import cache_backend
+        cache = cache_backend(self.initstring, timeout=1)
+        cache['test'] = 'test'
+        time.sleep(3)
+        def tmp(): #@IgnorePep8
+            cache['test']
+        self.assertRaises(KeyError, tmp)
+
+
+class CacheCull(Cache):
+
+    def test_cull(self):
+        from shove._imports import cache_backend
+        cache = cache_backend(self.initstring, max_entries=1)
+        cache['test1'] = 'test'
+        cache['test2'] = 'test2'
+        cache['test3'] = 'test3'
+        self.assertEquals(len(cache), 1)
+
+
+class TestSimpleCache(CacheCull, unittest.TestCase):
+
+    initstring = 'simple://'
+
+
+class TestSimpleLRUCache(NoTimeout, unittest.TestCase):
+
+    initstring = 'simplelru://'
+
+
+class TestMemoryCache(CacheCull, unittest.TestCase):
+
+    initstring = 'memory://'
+
+
+class TestMemoryLRUCache(NoTimeout, unittest.TestCase):
+
+    initstring = 'memlru://'
+
+
+class TestFileCache(CacheCull, unittest.TestCase):
+
+    initstring = 'file://test'
+
+    def tearDown(self):
+        import shutil
+        self.cache = None
+        shutil.rmtree('test')
+
+
+class TestFileLRUCache(NoTimeout, unittest.TestCase):
+
+    initstring = 'filelru://test2'
+
+    def tearDown(self):
+        import shutil
+        self.cache = None
+        shutil.rmtree('test2')
+
+
+class TestDBCache(CacheCull, unittest.TestCase):
+
+    initstring = 'sqlite:///'
+
+
+if not PY3:
+    class TestMemcache(Cache, Spawn, unittest.TestCase):
+
+        initstring = 'memcache://localhost:11211'
+        cmd = ['memcached']
+
+    class TestRedisCache(Cache, Spawn, unittest.TestCase):
+
+        initstring = 'redis://localhost:6379/0'
+        cmd = ['redis-server']
+
+
+if __name__ == '__main__':
+    unittest.main()

File tests/test_multishove.py

+# -*- coding: utf-8 -*-
+'''shove multishove tests'''
+
+from stuf.six import unittest
+
+
+def setUpModule():
+    import os
+    from tempfile import mkdtemp
+    TMP = mkdtemp()
+    os.chdir(TMP)
+
+
+class Multi(object):
+
+    def test__getitem__(self):
+        self.store['max'] = 3
+        self.store.sync()
+        self.assertEqual(self.store['max'], 3)
+
+    def test__setitem__(self):
+        self.store['max'] = 3
+        self.store.sync()
+        self.assertEqual(self.store['max'], 3)
+
+    def test__delitem__(self):
+        self.store['max'] = 3
+        self.store.sync()
+        del self.store['max']
+        self.store.sync()
+        self.assertEqual('max' in self.store, False)
+
+    def test_get(self):
+        self.store['max'] = 3
+        self.store.sync()
+        self.assertEqual(self.store.get('min'), None)
+
+    def test__cmp__(self):
+        from shove.core import MultiShove
+        tstore = MultiShove()
+        self.store['max'] = 3
+        tstore['max'] = 3
+        self.store.sync()
+        tstore.sync()
+        self.assertEqual(self.store, tstore)
+
+    def test__len__(self):
+        self.store['max'] = 3
+        self.store['min'] = 6
+        self.store['pow'] = 7
+        self.store.sync()
+        self.assertEqual(len(self.store), 3)
+
+    def test_clear(self):
+        self.store['max'] = 3
+        self.store['min'] = 6
+        self.store['pow'] = 7
+        self.store.clear()
+        self.assertEqual(len(self.store), 0)
+
+    def test_items(self):
+        self.store['max'] = 3
+        self.store['min'] = 6
+        self.store['pow'] = 7
+        self.store.sync()
+        slist = list(self.store.items())
+        self.assertEqual(('min', 6) in slist, True)
+
+    def test_keys(self):
+        self.store['max'] = 3
+        self.store['min'] = 6
+        self.store['pow'] = 7
+        self.store.sync()
+        slist = list(self.store.keys())
+        self.assertEqual('min' in slist, True)
+
+    def test_values(self):
+        self.store['max'] = 3
+        self.store['min'] = 6
+        self.store['pow'] = 7
+        self.store.sync()
+        slist = list(self.store.values())
+        self.assertEqual(6 in slist, True)
+
+    def test_pop(self):
+        self.store['max'] = 3
+        self.store['min'] = 6
+        self.store.sync()
+        item = self.store.pop('min')
+        self.store.sync()
+        self.assertEqual(item, 6)
+
+    def test_popitem(self):
+        self.store['max'] = 3
+        self.store['min'] = 6
+        self.store['pow'] = 7
+        self.store.sync()
+        item = self.store.popitem()
+        self.store.sync()
+        self.assertEqual(len(item) + len(self.store), 4)
+
+    def test_setdefault(self):
+        self.store['max'] = 3
+        self.store['min'] = 6
+        self.store['powl'] = 7
+        self.store.sync()
+        self.store.setdefault('pow', 8)
+        self.store.sync()
+        self.assertEqual(self.store['pow'], 8)
+
+    def test_update(self):
+        from shove.core import MultiShove
+        tstore = MultiShove()
+        tstore['max'] = 3
+        tstore['min'] = 6
+        tstore['pow'] = 7
+        self.store['max'] = 2
+        self.store['min'] = 3
+        self.store['pow'] = 7
+        self.store.update(tstore)
+        self.store.sync()
+        self.assertEqual(self.store['min'], 6)
+
+
+class TestMultiShove(Multi, unittest.TestCase):
+
+    stores = (
+        'simple://', 'dbm://one.dbm', 'memory://', 'file://two', 'sqlite://',
+    )
+
+    def setUp(self):
+        from shove.core import MultiShove
+        self.store = MultiShove(*self.stores, sync=0)
+
+    def tearDown(self):
+        import os
+        import shutil
+        self.store.close()
+        shutil.rmtree('two')
+        try:
+            os.remove('one.dbm')
+        except OSError:
+            os.remove('one.dbm.db')
+
+
+class TestThreadShove(unittest.TestCase):
+
+    stores = (
+        'simple://', 'memory://', 'file://six', 'sqlite://',
+    )
+
+    def setUp(self):
+        from shove.core import ThreadShove
+        self.store = ThreadShove(*self.stores, max_workers=3, sync=0)
+
+    def tearDown(self):
+        import shutil
+        self.store.close()
+        shutil.rmtree('six')
+
+
+if __name__ == '__main__':
+    unittest.main()

File tests/test_store.py

+# -*- coding: utf-8 -*-
+'''shove store tests'''
+
+from stuf.six import PY3, unittest, keys, values, items
+from tests.mixins import Spawn
+
+setUpModule = Spawn.setUpModule
+tearDownModule = Spawn.tearDownModule
+
+
+class Store(object):
+
+    def setUp(self):
+        from shove import Shove
+        self.store = Shove(
+            self.initstring, optimize=False, compress=True, sync=0,
+        )
+
+    def tearDown(self):
+        self.store.close()
+
+    def test__getitem__(self):
+        self.store['max'] = 3
+        self.store.sync()
+        self.assertEqual(self.store['max'], 3)
+
+    def test__setitem__(self):
+        self.store['max'] = 3
+        self.store['d'] = {'A': 1}, {'A': 1}
+        self.store['d'] = {'AA': 1}, {'A': 1}
+        self.store['d'] = {'AA': 1}, {'AA': 1}
+        self.store.sync()
+        self.assertEqual(self.store['max'], 3)
+
+    def test__delitem__(self):
+        self.store['max'] = 3
+        self.store.sync()
+        del self.store['max']
+        self.store.sync()
+        self.assertEqual('max' in self.store, False)
+
+    def test_get(self):
+        self.store['max'] = 3
+        self.store.sync()
+        self.assertEqual(self.store.get('min'), None)
+
+    def test__cmp__(self):
+        from shove import Shove
+        tstore = Shove()
+        self.store['max'] = 3
+        self.store.sync()
+        tstore['max'] = 3
+        self.assertEqual(self.store, tstore)
+
+    def test__len__(self):
+        self.store['max'] = 3
+        self.store['min'] = 6
+        self.store.sync()
+        self.assertEqual(len(self.store), 2)
+
+    def test_items(self):
+        self.store['max'] = 3
+        self.store['min'] = 6
+        self.store['pow'] = 7
+        self.store.sync()
+        slist = list(items(self.store))
+        self.assertEqual(('min', 6) in slist, True)
+
+    def test_keys(self):
+        self.store['max'] = 3
+        self.store['min'] = 6
+        self.store['pow'] = 7
+        self.store.sync()
+        slist = list(keys(self.store))
+        self.assertEqual('min' in slist, True)
+
+    def test_values(self):
+        self.store['max'] = 3
+        self.store['min'] = 6
+        self.store['pow'] = 7
+        self.store.sync()
+        slist = list(values(self.store))
+        self.assertEqual(6 in slist, True)
+
+    def test_pop(self):
+        self.store['max'] = 3
+        self.store['min'] = 6
+        self.store.sync()
+        item = self.store.pop('min')
+        self.store.sync()
+        self.assertEqual(item, 6)
+
+    def test_setdefault(self):
+        self.store['max'] = 3
+        self.store['min'] = 6
+        self.store.sync()
+        self.assertEqual(self.store.setdefault('pow', 8), 8)
+        self.store.sync()
+        self.assertEqual(self.store['pow'], 8)
+
+    def test_update(self):
+        from shove import Shove
+        tstore = Shove()
+        tstore['max'] = 3
+        tstore['min'] = 6
+        tstore['pow'] = 7
+        self.store['max'] = 2
+        self.store['min'] = 3
+        self.store['pow'] = 7
+        self.store.update(tstore)
+        self.store.sync()
+        self.assertEqual(self.store['min'], 6)
+
+    def test_clear(self):
+        self.store['max'] = 3
+        self.store['min'] = 6
+        self.store['pow'] = 7
+        self.store.sync()
+        self.store.clear()
+        self.store.sync()
+        self.assertEqual(len(self.store), 0)
+
+    def test_popitem(self):
+        self.store['max'] = 3
+        self.store['min'] = 6
+        self.store['pow'] = 7
+        self.store.sync()
+        item = self.store.popitem()
+        self.store.sync()
+        self.assertEqual(len(item) + len(self.store), 4)
+
+    def test_close(self):
+        self.store.close()
+        self.assertEqual(self.store._store, None)
+        self.assertEqual(self.store._buffer, None)
+        self.assertEqual(self.store._cache, None)
+