U
    luf                     @   s  d Z ddlZddlZddlZddlZddlZddlmZ ddlm	Z	 zddl
Z
ddl
mZ W n ek
rt   dZ
Y nX edk rdZ
ddlmZ ddlZddlZddlZejdZd	Zd
d Zejdd Zdd Zejdd Zejdd Zejdd Zejdd Zejdd Zejdd Zejdd Z dd Z!d dd!d"d#d$Z"ee"d%d&Z#ejd'd( Z$ejd)d* Z%ejd+d, Z&ejd-d. Z'dS )/z!pytest configuration and fixtures    N)partial)Thread)version_info)   )IOLoopZZMQ_TEST_TIMEOUT
   c                 C   s4   | D ]*}t |jr|d t |jrtqdS )a+  This function is automatically run by pytest passing all collected test
    functions.
    We use it to add asyncio marker to all async tests and assert we don't use
    test functions that are async generators which wouldn't make sense.
    It is no longer required with pytest-asyncio >= 0.17
    asyncioN)inspectiscoroutinefunctionobjZ
add_markerisasyncgenfunctionAssertionError)itemsitem r   6/tmp/pip-unpacked-wheel-h6ekxre8/zmq/tests/conftest.pypytest_collection_modifyitems   s    
r   c                    sP   t dkrt  t  t | ks(t j| ks6t fdd}|	|  S )z4Create tornado io_loop on current asyncio event loopNc                      s    j dd d S )NT)Zall_fds)closer   io_loopr   r   _close4   s    zio_loop.<locals>._close)
tornadopytestskipr   currentr   Zget_event_loopr   Zasyncio_loopZaddfinalizer)
event_looprequestr   r   r   r   r   +   s    
r   c                 C   sN   t | jd}d|_|  |j|d | rJdtjjj	_
td|  ddS )z"Terminate a context with a timeout)targetTtimeoutNzcontext z8 could not terminate, open sockets likely remain in test)r   Ztermdaemonstartjoinis_alivezmqsugarcontextContext	_instanceRuntimeError)ctxr   tr   r   r   term_context;   s    
r,   c                  c   s.   t  } | V  |   ttj ji ks*td S N)r   Znew_event_loopr   dictr$   Z
_selectorsr   )Zloopr   r   r   r   I   s    r   c                  C   s6   t tdrtsdS dd } ttj|  tt dS )z~Set timeout using SIGALRM

    Avoids infinite hang in context.term for an unclean context,
    raising an error instead.
    SIGALRMNc                  W   s   t dt dd S )NzTest did not complete in z seconds)TimeoutErrortest_timeout_seconds)argsr   r   r   _alarm_timeout\   s    z'sigalrm_timeout.<locals>._alarm_timeout)hasattrsignalr1   r/   alarm)r3   r   r   r   sigalrm_timeoutR   s
    r7   c                   C   s   t jS )zaContext class fixture

    Override in modules to specify a different class (e.g. zmq.green)
    )r$   r'   r   r   r   r   r'   c   s    r'   c              	   c   sL   t  }|V  |D ]6}zt|t W q tk
rD   dtjjj_ Y qX qdS )zFFixture to track contexts used in tests

    For cleanup purposes
    N)	setr,   teardown_timeout	Exceptionr$   r%   r&   r'   r(   )r7   contextsr*   r   r   r   r;   l   s    r;   c                 C   s   |  }| | |S )zFixture for shared context)add)r'   r;   r*   r   r   r   r&   }   s    
r&   c                 c   s:   g }|V  |D ]}|  |j q|D ]}|jdd q$d S )Nr   )linger)r<   r&   r   )r;   socketssocketr   r   r   r>      s    r>   c                    s    fdd}|S )z:Fixture to create sockets, while tracking them for cleanupc                     s    j | |}| |S r-   )r?   append)r2   kwargssr&   r>   r   r   
new_socket   s    
zsocket.<locals>.new_socketr   )r&   r>   rD   r   rC   r   r?      s    r?   c              
   c   sx   z
d V  W nP t jk
rZ } z0|j| ksJtdt |  dt |j W 5 d }~X Y nX tdt |  d d S )Nzwrong error raised, expected z got z	Expected z, no error raised)r$   ZZMQErrorerrnor   r   Zfail)rE   er   r   r   assert_raises_errno   s    
rG   r   F)r   flags	multipartc          	      K   st   t  dkrtd t j| gg g |d\}}}|s<tdt j|ddB |d< |r\| jn| j	}|f d|i|S )zIcall recv[_multipart] in a way that raises if there is nothing to receive)      r   g?r   zShould have received a messagerH   r   )
r$   Zzmq_version_infotimesleepselectr   ZDONTWAITgetrecv_multipartrecv)	r?   r   rH   rI   rA   rwxrQ   r   r   r   rQ      s    
rQ   T)rI   c                    s   t jt jdf fdd	}|S )Nztcp://127.0.0.1c                    sB    | }d|_ ||} |}d|_ || d|  ||fS )z/Create a bound socket pair using a random port.r   :)r=   Zbind_to_random_portconnect)Ztype1Ztype2Z	interfaces1ports2r?   r   r   create_bound_pair   s    
z,create_bound_pair.<locals>.create_bound_pair)r$   ZPAIR)r?   r[   r   rZ   r   r[      s    
r[   c                 C   s   |  S r-   r   r[   r   r   r   
bound_pair   s    r]   c                 C   s   | t jt jS r-   )r$   ZPUSHZPULLr\   r   r   r   	push_pull   s    r^   c                 C   s   | t jt jS r-   )r$   ZDEALERZROUTERr\   r   r   r   dealer_router   s    r_   )(__doc__r   r	   osr5   rL   	functoolsr   	threadingr   r   r   ImportErrorZtornado.ioloopr   r   r$   Zzmq.asyncioenvironrO   r1   r9   r   Zfixturer   r,   r   r7   r'   r;   r&   r>   r?   rG   rQ   rP   r[   r]   r^   r_   r   r   r   r   <module>   sb   











