Skip to content
test_persistent_dict.py 6.91 KiB
Newer Older
Andreas Klöckner's avatar
Andreas Klöckner committed
from __future__ import division, with_statement, absolute_import

import pytest  # noqa
import sys  # noqa
from six.moves import range
from six.moves import zip
Matt Wala's avatar
Matt Wala committed
from pytools.persistent_dict import (
        PersistentDict, WriteOncePersistentDict, NoSuchEntryError,
        ReadOnlyEntryError)
class PDictTestingKeyOrValue(object):
    def __init__(self, val, hash_key=None):
        self.val = val
        if hash_key is None:
            hash_key = val
        self.hash_key = hash_key
    def __getstate__(self):
        return {"val": self.val, "hash_key": self.hash_key}
    def __eq__(self, other):
        return self.val == other.val
    def __ne__(self, other):
        return not self.__eq__(other)
    def update_persistent_hash(self, key_hash, key_builder):
        key_builder.rec(key_hash, self.hash_key)
Matt Wala's avatar
Matt Wala committed
    def __repr__(self):
        return "PDictTestingKeyOrValue(val=%r,hash_key=%r)" % (
                (self.val, self.hash_key))
Matt Wala's avatar
Matt Wala committed
    __str__ = __repr__
def test_persistent_dict_storage_and_lookup():
    try:
        tmpdir = tempfile.mkdtemp()
Matt Wala's avatar
Matt Wala committed
        pdict = PersistentDict("pytools-test", container_dir=tmpdir)
        from random import randrange
        def rand_str(n=20):
            return "".join(
                    chr(65+randrange(26))
                    for i in range(n))
        keys = [(randrange(2000), rand_str(), None) for i in range(20)]
        values = [randrange(2000) for i in range(20)]

        d = dict(list(zip(keys, values)))

        # {{{ check lookup

        for k, v in zip(keys, values):
            pdict[k] = v

        for k, v in d.items():
            assert d[k] == pdict[k]

        # }}}

        # {{{ check updating

        for k, v in zip(keys, values):
            pdict[k] = v + 1

        for k, v in d.items():
            assert d[k] + 1 == pdict[k]

        # }}}

        # {{{ check not found

        with pytest.raises(NoSuchEntryError):
            pdict[3000]

        # }}}

    finally:
        shutil.rmtree(tmpdir)


def test_persistent_dict_deletion():
    try:
        tmpdir = tempfile.mkdtemp()
Matt Wala's avatar
Matt Wala committed
        pdict = PersistentDict("pytools-test", container_dir=tmpdir)

        pdict[0] = 0
        del pdict[0]

        with pytest.raises(NoSuchEntryError):
            pdict[0]

        with pytest.raises(NoSuchEntryError):
            del pdict[1]

    finally:
        shutil.rmtree(tmpdir)


def test_persistent_dict_synchronization():
    try:
        tmpdir = tempfile.mkdtemp()
Matt Wala's avatar
Matt Wala committed
        pdict1 = PersistentDict("pytools-test", container_dir=tmpdir)
        pdict2 = PersistentDict("pytools-test", container_dir=tmpdir)

        # check lookup
        pdict1[0] = 1
        assert pdict2[0] == 1

        # check updating
        pdict1[0] = 2
        assert pdict2[0] == 2

        # check deletion
        del pdict1[0]
        with pytest.raises(NoSuchEntryError):
            pdict2[0]

    finally:
        shutil.rmtree(tmpdir)


def test_persistent_dict_cache_collisions():
    try:
        tmpdir = tempfile.mkdtemp()
Matt Wala's avatar
Matt Wala committed
        pdict = PersistentDict("pytools-test", container_dir=tmpdir)

        key1 = PDictTestingKeyOrValue(1, hash_key=0)
        key2 = PDictTestingKeyOrValue(2, hash_key=0)

        pdict[key1] = 1

Matt Wala's avatar
Matt Wala committed
        # check lookup
        with pytest.warns(UserWarning):
            with pytest.raises(NoSuchEntryError):
                pdict[key2]

Matt Wala's avatar
Matt Wala committed
        # check deletion
        with pytest.warns(UserWarning):
            with pytest.raises(NoSuchEntryError):
                del pdict[key2]

Matt Wala's avatar
Matt Wala committed
        # check presence after deletion
        pdict[key1]

    finally:
        shutil.rmtree(tmpdir)


def test_persistent_dict_clear():
    try:
        tmpdir = tempfile.mkdtemp()
        pdict = PersistentDict("pytools-test", container_dir=tmpdir)

        pdict[0] = 1
        pdict[0]
        pdict.clear()

        with pytest.raises(NoSuchEntryError):
            pdict[0]

Matt Wala's avatar
Matt Wala committed
@pytest.mark.parametrize("in_mem_cache_size", (0, 256))
def test_write_once_persistent_dict_storage_and_lookup(in_mem_cache_size):
    try:
        tmpdir = tempfile.mkdtemp()
Matt Wala's avatar
Matt Wala committed
        pdict = WriteOncePersistentDict(
                "pytools-test", container_dir=tmpdir,
                in_mem_cache_size=in_mem_cache_size)

        # check lookup
        pdict[0] = 1
        assert pdict[0] == 1
        # do two lookups to test the cache
        assert pdict[0] == 1

        # check updating
        with pytest.raises(ReadOnlyEntryError):
            pdict[0] = 2

        # check not found
        with pytest.raises(NoSuchEntryError):
            pdict[1]

    finally:
        shutil.rmtree(tmpdir)


def test_write_once_persistent_dict_lru_policy():
    try:
        tmpdir = tempfile.mkdtemp()
Matt Wala's avatar
Matt Wala committed
        pdict = WriteOncePersistentDict(
                "pytools-test", container_dir=tmpdir, in_mem_cache_size=3)

        pdict[1] = PDictTestingKeyOrValue(1)
        pdict[2] = PDictTestingKeyOrValue(2)
        pdict[3] = PDictTestingKeyOrValue(3)
        pdict[4] = PDictTestingKeyOrValue(4)

        val1 = pdict[1]
        assert pdict[1] is val1
        pdict[2]
        assert pdict[1] is val1
Matt Wala's avatar
Matt Wala committed
        pdict[2]
        pdict[3]
        assert pdict[1] is val1
        pdict[2]
Matt Wala's avatar
Matt Wala committed
        pdict[3]
        pdict[2]
Matt Wala's avatar
Matt Wala committed
        pdict[2]
        pdict[3]
        pdict[4]
        assert pdict[1] is not val1
    finally:
        shutil.rmtree(tmpdir)
def test_write_once_persistent_dict_synchronization():
    try:
        tmpdir = tempfile.mkdtemp()
Matt Wala's avatar
Matt Wala committed
        pdict1 = WriteOncePersistentDict("pytools-test", container_dir=tmpdir)
        pdict2 = WriteOncePersistentDict("pytools-test", container_dir=tmpdir)
        # check lookup
        pdict1[1] = 0
        assert pdict2[1] == 0
        # check updating
        with pytest.raises(ReadOnlyEntryError):
            pdict2[1] = 1
    finally:
        shutil.rmtree(tmpdir)
def test_write_once_persistent_dict_cache_collisions():
    try:
        tmpdir = tempfile.mkdtemp()
Matt Wala's avatar
Matt Wala committed
        pdict = WriteOncePersistentDict("pytools-test", container_dir=tmpdir)
        key1 = PDictTestingKeyOrValue(1, hash_key=0)
        key2 = PDictTestingKeyOrValue(2, hash_key=0)
        pdict[key1] = 1
Matt Wala's avatar
Matt Wala committed
        # check lookup
Matt Wala's avatar
Matt Wala committed
        with pytest.warns(UserWarning):
            with pytest.raises(NoSuchEntryError):
                pdict[key2]
        # check update
        with pytest.raises(ReadOnlyEntryError):
            pdict[key2] = 1

    finally:
        shutil.rmtree(tmpdir)
Matt Wala's avatar
Matt Wala committed
def test_write_once_persistent_dict_clear():
    try:
        tmpdir = tempfile.mkdtemp()
        pdict = WriteOncePersistentDict("pytools-test", container_dir=tmpdir)
Matt Wala's avatar
Matt Wala committed
        pdict[0] = 1
        pdict[0]
        pdict.clear()
Matt Wala's avatar
Matt Wala committed
        with pytest.raises(NoSuchEntryError):
            pdict[0]
    finally:
        shutil.rmtree(tmpdir)
if __name__ == "__main__":
    if len(sys.argv) > 1:
        exec(sys.argv[1])
    else:
        from py.test.cmdline import main
        main([__file__])