B
    QT                 @   s   d Z G dd dZddlmZ ddlZddlmZ ddlm	Z	 yddl
mZ W n( ek
rv   dd	l
mZ d
d ZY nX dd ZdZed Zd\ZZeedddd ZeeeZdd Zdd ZG dd dejZdS )a  The Python interpreter may switch between threads inbetween bytecode
execution.  Bytecode execution in fastcache may occur during:
(1) Calls to make_key which will call the __hash__ methods of the args and
(2) `PyDict_Get(Set)Item` calls rely on Python comparisons (i.e, __eq__)
    to determine if a match has been found

A good test for threadsafety is then to cache a function which takes user
defined Python objects that have __hash__ and __eq__ methods which live in
Python land rather built-in land.

The test should not only ensure that the correct result is acheived (and no
segfaults) but also assess memory leaks.

The thread switching interval can be altered using sys.setswitchinterval.
c               @   s(   e Zd ZdZdd Zdd Zdd ZdS )		PythonIntzD Wrapper for an integer with python versions of __eq__ and __hash__.c             C   s
   || _ d S )N)value)selfval r   :lib/python3.7/site-packages/fastcache/tests/test_thread.py__init__   s    zPythonInt.__init__c             C   s
   t | jS )N)hashr   )r   r   r   r   __hash__   s    zPythonInt.__hash__c             C   s&   t |tstdt| | j|jkS )Nz"PythonInt cannot be compared to %s)
isinstancer   	TypeErrortyper   )r   otherr   r   r   __eq__   s    
zPythonInt.__eq__N)__name__
__module____qualname____doc__r   r	   r   r   r   r   r   r      s   r       )randintN)
clru_cache)Thread)setswitchinterval)setcheckintervalc             C   s   t t| S )N)r   int)ir   r   r   setinterval(   s    r   c             C   s0   x| D ]}|   qW x| D ]}|  qW d S )N)startjoin)threadstr   r   r   run_threads,   s    

r    i-     )r!   
   F)maxsizetypedc             C   s2   | j }|dk r|S tt|d tt|d  S )z$Terrible Fibonacci number generator.   r!   )r   fibr   )nvr   r   r   r&   6   s    r&   c             C   sP   xJt | D ]>}ttttkr$t  ttt}t|kr
t	dt|f q
W dS )z" Run Fibonacci generator r times. zExpected %d, Got %dN)
ranger   RAND_MINRAND_MAXr&   cache_clearr   FIBRESULT
ValueError)rr   resr   r   r   run_fib_with_clear?   s    r2   c             C   s:   x4t | D ](}ttt}t|kr
tdt|f q
W dS )z" Run Fibonacci generator r times. zExpected %d, Got %dN)r)   r&   r   r-   r.   r/   )r0   r   r1   r   r   r   run_fib_with_statsH   s    r3   c               @   s(   e Zd ZdZdd Zdd Zdd ZdS )	Test_Threadingz# Threadsafety Tests for lru_cache. c             C   s   t d d| _d| _d S )Ngư>   i  )r   
numthreadsrepeat)r   r   r   r   setUpS   s    zTest_Threading.setUpc                s0    fddt  jD }t|  dd dS )z/ randomly clear the cache during calls to fib. c                s   g | ]}t t jfd qS ))targetargs)r   r2   r7   ).0_)r   r   r   
<listcomp>[   s   zBTest_Threading.test_thread_random_cache_clears.<locals>.<listcomp>r   N)r)   r6   r    assertEqual)r   r   r   )r   r   test_thread_random_cache_clearsX   s    
z.Test_Threading.test_thread_random_cache_clearsc                sT   t    fddt jD }t| t  \}}}} |t  |t dS )zN Run thread safety test to make sure the cache statistics
        are correct.c                s   g | ]}t t jfd qS ))r9   r:   )r   r3   r7   )r;   r<   )r   r   r   r=   e   s   z9Test_Threading.test_thread_cache_info.<locals>.<listcomp>N)r&   r,   r)   r6   r    
cache_infor>   
CACHE_SIZE)r   r   hitsmissesr#   currsizer   )r   r   test_thread_cache_infoa   s    
z%Test_Threading.test_thread_cache_infoN)r   r   r   r   r8   r?   rE   r   r   r   r   r4   P   s   	r4   )r   r   Zrandomr   ZunittestZ	fastcacher   	lru_cacheZ	threadingr   sysr   r   ImportErrorr   r    rA   r-   r*   r+   r&   r.   r2   r3   ZTestCaser4   r   r   r   r   <module>   s&   	