U
    uë]j'  ã                   @   s†   d dl 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 G dd„ dƒZG dd„ deƒZ	G dd„ dej
ƒZG d	d
„ d
ƒZdd„ ZdS )é    N)ÚCancelledErrorc                   @   sN   e Zd ZdZdZddd„Zdd„ Zd	d
„ Zdd„ Zdd„ Z	dd„ Z
dd„ ZdS )ÚBaseDaphneTestingInstancez–
    Launches an instance of Daphne in a subprocess, with a host and port
    attribute allowing you to call it.

    Works as a context manager.
    é   FNc                C   s"   || _ || _d| _|| _|| _d S )Nz	127.0.0.1)ÚxffÚhttp_timeoutÚhostÚrequest_buffer_sizeÚapplication)Úselfr   r   r   r	   © r   úWc:\users\psant\downloads\hotstarbackend\school\venv\Lib\site-packages\daphne/testing.pyÚ__init__   s
    z"BaseDaphneTestingInstance.__init__c                 C   s   | j S ©N)r	   ©r
   r   r   r   Úget_application   s    z)BaseDaphneTestingInstance.get_applicationc                 C   sÀ   i }| j r| j |d< | jr2d|d< d|d< d|d< | jrB| j|d< t| j| j|| j| jd	�| _| j 	¡  | jj
 | j¡rˆ| jjj| _| S | jj ¡ ržtd
ƒ‚n| jj d¡\}}td| ƒ‚d S )Nr   zX-Forwarded-ForZproxy_forwarded_address_headerzX-Forwarded-PortZproxy_forwarded_port_headerzX-Forwarded-ProtoZproxy_forwarded_proto_headerr   )r   r   ÚkwargsÚsetupÚteardownz(Daphne did not start up, no error caughtFzDaphne did not start up:
%s)r   r   r   ÚDaphneProcessr   r   Úprocess_setupÚprocess_teardownÚprocessÚstartÚreadyÚwaitÚstartup_timeoutÚportÚvalueÚerrorsÚemptyÚRuntimeErrorÚget)r
   r   ÚerrorÚ	tracebackr   r   r   Ú	__enter__    s0    

û

z#BaseDaphneTestingInstance.__enter__c                 C   s   | j  ¡  | ` d S r   )r   Ú	terminate)r
   Úexc_typeÚ	exc_valuer#   r   r   r   Ú__exit__@   s    
z"BaseDaphneTestingInstance.__exit__c                 C   s   dS )zF
        Called by the process just before it starts serving.
        Nr   r   r   r   r   r   E   s    z'BaseDaphneTestingInstance.process_setupc                 C   s   dS )zC
        Called by the process just after it stops serving
        Nr   r   r   r   r   r   K   s    z*BaseDaphneTestingInstance.process_teardownc                 C   s   d S r   r   r   r   r   r   Úget_receivedQ   s    z&BaseDaphneTestingInstance.get_received)FNN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r   r   r$   r(   r   r   r)   r   r   r   r   r   
   s        ÿ
	 r   c                       s8   e Zd Z‡ fdd„Z‡ fdd„Zdd„ Zdd„ Z‡  ZS )	ÚDaphneTestingInstancec                    s,   t  ¡ | _tƒ j||dt| jd�i—Ž d S )Nr	   )Úlock)ÚmultiprocessingÚLockr/   Úsuperr   ÚTestApplication)r
   Úargsr   ©Ú	__class__r   r   r   V   s    
zDaphneTestingInstance.__init__c                    s   t  ¡  t  ¡  tƒ  ¡ S r   )r3   Údelete_setupÚdelete_resultr2   r$   r   r5   r   r   r$   Z   s    zDaphneTestingInstance.__enter__c              	   C   s\   z| j � t ¡ }W 5 Q R X W n tk
r:   tdƒ‚Y nX d|krL|d ‚|d |d fS )a$  
        Returns the scope and messages the test application has received
        so far. Note you'll get all messages since scope start, not just any
        new ones since the last call.

        Also checks for any exceptions in the application. If there are,
        raises them.
        zNo results available yet.Ú	exceptionÚscopeÚmessages)r/   r3   Úload_resultÚFileNotFoundErrorÚ
ValueError)r
   Zinner_resultr   r   r   r)   `   s    	z"DaphneTestingInstance.get_receivedc                 C   s   t j|d� dS )z’
        Adds messages for the application to send back.
        The next time it receives an incoming message, it will reply with these.
        )Úresponse_messagesN)r3   Ú
save_setup)r
   r;   r   r   r   Úadd_send_messagess   s    z'DaphneTestingInstance.add_send_messages)r*   r+   r,   r   r$   r)   rA   Ú__classcell__r   r   r5   r   r.   U   s   r.   c                       s2   e Zd ZdZd	‡ fdd„	Zdd„ Zdd„ Z‡  ZS )
r   z“
    Process subclass that launches and runs a Daphne instance, communicating the
    port it ends up listening on back to the parent process.
    Nc                    sP   t ƒ  ¡  || _|| _|pi | _|| _|| _t d¡| _	t 
¡ | _t ¡ | _d S )NÚi)r2   r   r   r   r   r   r   r0   ÚValuer   ÚEventr   ÚQueuer   )r
   r   r   r   r   r   r5   r   r   r   �   s    


zDaphneProcess.__init__c              
   C   sÞ   t ƒ  ddlm} ddlm} ddlm} |  ¡ }zp|| jdd�}|f ||ddœ| j	—Ž| _| 
d	| j¡ | jd k	r||  ¡  z| j ¡  W 5 | jd k	rž|  ¡  X W n6 tk
rØ } z| j |t ¡ f¡ W 5 d }~X Y nX d S )
Nr   ©Úreactoré   )Ú"build_endpoint_description_strings)ÚServer)r   r   F)r	   Ú	endpointsZsignal_handlersçš™™™™™¹?)Ú_reinstall_reactorÚtwisted.internetrH   rL   rJ   ÚserverrK   r   r   r   Ú	callLaterÚresolve_portr   r   ÚrunÚBaseExceptionr   Úputr#   Ú
format_exc)r
   rH   rJ   rK   r	   rL   Úer   r   r   rS   Œ   s.    ýü

zDaphneProcess.runc                 C   sF   ddl m} | jjr4| jjd d | j_| j ¡  n| d| j	¡ d S )Nr   rG   rI   rM   )
rO   rH   rP   Zlistening_addressesr   r   r   ÚsetrQ   rR   )r
   rH   r   r   r   rR   ±   s
    zDaphneProcess.resolve_port)NNN)r*   r+   r,   r-   r   rS   rR   rB   r   r   r5   r   r   {   s   %r   c                   @   s˜   e Zd ZdZej e ¡ d¡Z	ej e ¡ d¡Z
dd„ Zdd„ Zedd	„ ƒZed
d„ ƒZedd„ ƒZedd„ ƒZedd„ ƒZedd„ ƒZedd„ ƒZdS )r3   zz
    An application that receives one or more messages, sends a response,
    and then quits the server. For testing.
    zsetup.testiozresult.testioc                 C   s   || _ g | _d S r   )r/   r;   )r
   r/   r   r   r   r   Ä   s    zTestApplication.__init__c              
   Ã   sØ   || _ t d¡ zˆ| j |ƒ I d H ¡ | j ¡  t d| jd ¡ |  | j | j¡ | j ¡  |  	¡ }|  
¡  |d D ]}||ƒI d H  t d|¡ qtqW n: tk
rÒ } zt|tƒr¸‚ n
|  |¡ W 5 d }~X Y nX d S )Nztest app coroutine aliveztest app received %réÿÿÿÿr?   ztest app sent %r)r:   ÚloggingÚdebugr;   Úappendr/   ÚacquireÚsave_resultÚreleaseÚ
load_setupr7   Ú	ExceptionÚ
isinstancer   Úsave_exception)r
   r:   ZreceiveÚsendr   ÚmessagerW   r   r   r   Ú__call__È   s"    



zTestApplication.__call__c              	   C   s,   t | jdƒ�}t d|i|¡ W 5 Q R X dS )z+
        Stores setup information.
        Úwbr?   N)ÚopenÚsetup_storageÚpickleÚdump)Úclsr?   Úfhr   r   r   r@   á   s    zTestApplication.save_setupc              
   C   sR   z0t | jdƒ�}t |¡W  5 Q R £ W S Q R X W n tk
rL   dg i Y S X dS )z(
        Returns setup details.
        Úrbr?   N)rh   ri   rj   Úloadr=   ©rl   rm   r   r   r   r`   é   s
    "zTestApplication.load_setupc              	   C   s.   t | jdƒ�}t ||dœ|¡ W 5 Q R X dS )ú�
        Saves details of what happened to the result storage.
        We could use pickle here, but that seems wrong, still, somehow.
        rg   )r:   r;   N©rh   Úresult_storagerj   rk   )rl   r:   r;   rm   r   r   r   r^   ô   s    zTestApplication.save_resultc              	   C   s,   t | jdƒ�}t d|i|¡ W 5 Q R X dS )rq   rg   r9   Nrr   )rl   r9   rm   r   r   r   rc   ý   s    zTestApplication.save_exceptionc              
   C   s.   t | jdƒ�}t |¡W  5 Q R £ S Q R X dS )z)
        Returns result details.
        rn   N)rh   rs   rj   ro   rp   r   r   r   r<     s    zTestApplication.load_resultc                 C   s*   zt  | j¡ W n tk
r$   Y nX dS )z-
        Clears setup storage files.
        N)ÚosÚunlinkri   ÚOSError©rl   r   r   r   r7     s    zTestApplication.delete_setupc                 C   s*   zt  | j¡ W n tk
r$   Y nX dS )z.
        Clears result storage files.
        N)rt   ru   rs   rv   rw   r   r   r   r8     s    zTestApplication.delete_resultN)r*   r+   r,   r-   rt   ÚpathÚjoinÚtempfileÚ
gettempdirri   rs   r   rf   Úclassmethodr@   r`   r^   rc   r<   r7   r8   r   r   r   r   r3   »   s&   






	r3   c                  C   s`   dd l } dd l}ddlm} d|jkr.|jd= d|jkr@|jd= |  ¡ }| |¡ |  |¡ d S )Nr   )Úasyncioreactorztwisted.internet.reactorzdaphne.server)ÚasyncioÚsysrO   r}   ÚmodulesÚnew_event_loopÚinstallÚset_event_loop)r~   r   r}   Z
event_loopr   r   r   rN   #  s    


rN   )rZ   r0   rt   rj   rz   r#   Úconcurrent.futuresr   r   r.   ÚProcessr   r3   rN   r   r   r   r   Ú<module>   s   K&@h