Aluode/PerceptionLabPortable
0
1import asyncio2import gc3import shutil4 5import pytest6 7from joblib.memory import (8 AsyncMemorizedFunc,9 AsyncNotMemorizedFunc,10 MemorizedResult,11 Memory,12 NotMemorizedResult,13)14from joblib.test.common import np, with_numpy15from joblib.testing import raises16 17from .test_memory import corrupt_single_cache_item, monkeypatch_cached_func_warn18 19 20async def check_identity_lazy_async(func, accumulator, location):21 """Similar to check_identity_lazy_async for coroutine functions"""22 memory = Memory(location=location, verbose=0)23 func = memory.cache(func)24 for i in range(3):25 for _ in range(2):26 value = await func(i)27 assert value == i28 assert len(accumulator) == i + 129 30 31@pytest.mark.asyncio32async def test_memory_integration_async(tmpdir):33 accumulator = list()34 35 async def f(n):36 await asyncio.sleep(0.1)37 accumulator.append(1)38 return n39 40 await check_identity_lazy_async(f, accumulator, tmpdir.strpath)41 42 # Now test clearing43 for compress in (False, True):44 for mmap_mode in ("r", None):45 memory = Memory(46 location=tmpdir.strpath,47 verbose=10,48 mmap_mode=mmap_mode,49 compress=compress,50 )51 # First clear the cache directory, to check that our code can52 # handle that53 # NOTE: this line would raise an exception, as the database54 # file is still open; we ignore the error since we want to55 # test what happens if the directory disappears56 shutil.rmtree(tmpdir.strpath, ignore_errors=True)57 g = memory.cache(f)58 await g(1)59 g.clear(warn=False)60 current_accumulator = len(accumulator)61 out = await g(1)62 63 assert len(accumulator) == current_accumulator + 164 # Also, check that Memory.eval works similarly65 evaled = await memory.eval(f, 1)66 assert evaled == out67 assert len(accumulator) == current_accumulator + 168 69 # Now do a smoke test with a function defined in __main__, as the name70 # mangling rules are more complex71 f.__module__ = "__main__"72 memory = Memory(location=tmpdir.strpath, verbose=0)73 await memory.cache(f)(1)74 75 76@pytest.mark.asyncio77async def test_no_memory_async():78 accumulator = list()79 80 async def ff(x):81 await asyncio.sleep(0.1)82 accumulator.append(1)83 return x84 85 memory = Memory(location=None, verbose=0)86 gg = memory.cache(ff)87 for _ in range(4):88 current_accumulator = len(accumulator)89 await gg(1)90 assert len(accumulator) == current_accumulator + 191 92 93@with_numpy94@pytest.mark.asyncio95async def test_memory_numpy_check_mmap_mode_async(tmpdir, monkeypatch):96 """Check that mmap_mode is respected even at the first call"""97 98 memory = Memory(location=tmpdir.strpath, mmap_mode="r", verbose=0)99 100 @memory.cache()101 async def twice(a):102 return a * 2103 104 a = np.ones(3)105 b = await twice(a)106 c = await twice(a)107 108 assert isinstance(c, np.memmap)109 assert c.mode == "r"110 111 assert isinstance(b, np.memmap)112 assert b.mode == "r"113 114 # Corrupts the file, Deleting b and c mmaps115 # is necessary to be able edit the file116 del b117 del c118 gc.collect()119 corrupt_single_cache_item(memory)120 121 # Make sure that corrupting the file causes recomputation and that122 # a warning is issued.123 recorded_warnings = monkeypatch_cached_func_warn(twice, monkeypatch)124 d = await twice(a)125 assert len(recorded_warnings) == 1126 exception_msg = "Exception while loading results"127 assert exception_msg in recorded_warnings[0]128 # Asserts that the recomputation returns a mmap129 assert isinstance(d, np.memmap)130 assert d.mode == "r"131 132 133@pytest.mark.asyncio134async def test_call_and_shelve_async(tmpdir):135 async def f(x, y=1):136 await asyncio.sleep(0.1)137 return x**2 + y138 139 # Test MemorizedFunc outputting a reference to cache.140 for func, Result in zip(141 (142 AsyncMemorizedFunc(f, tmpdir.strpath),143 AsyncNotMemorizedFunc(f),144 Memory(location=tmpdir.strpath, verbose=0).cache(f),145 Memory(location=None).cache(f),146 ),147 (148 MemorizedResult,149 NotMemorizedResult,150 MemorizedResult,151 NotMemorizedResult,152 ),153 ):154 for _ in range(2):155 result = await func.call_and_shelve(2)156 assert isinstance(result, Result)157 assert result.get() == 5158 159 result.clear()160 with raises(KeyError):161 result.get()162 result.clear() # Do nothing if there is no cache.163 164 165@pytest.mark.asyncio166async def test_memorized_func_call_async(memory):167 async def ff(x, counter):168 await asyncio.sleep(0.1)169 counter[x] = counter.get(x, 0) + 1170 return counter[x]171 172 gg = memory.cache(ff, ignore=["counter"])173 174 counter = {}175 assert await gg(2, counter) == 1176 assert await gg(2, counter) == 1177 178 x, meta = await gg.call(2, counter)179 assert x == 2, "f has not been called properly"180 assert isinstance(meta, dict), "Metadata are not returned by MemorizedFunc.call."181 