U
    
W[Ã*  ã                   @   s:  d Z ddlmZmZ ddlZddlZddlmZmZ ddl	m
Z
 ddlmZ ddlmZ ddlmZ dd	lmZ dd
lmZ ddlmZ ddlmZ ddlmZmZ ddlmZ ddlmZ ddl m!Z!m"Z" ddl#m$Z$m%Z% ddl#m&Z&m'Z' ddl(m)Z) ddl*m+Z+ ddl,m-Z- e.ƒ Z/G dd„ deƒZ0G dd„ deƒZ1dS )z
Tests for L{twisted.web.tap}.
é    )Úabsolute_importÚdivisionN)ÚreactorÚ	endpoints)ÚIReactorUNIX)ÚFilePath)ÚrequireModule)Ú
ThreadPool)Ú
UsageError)ÚPBServerFactory)ÚTestCase)Údemo)ÚResourcePublisherÚUserDirectory)ÚPythonScript)ÚSite)ÚDataÚFile)ÚOptionsÚmakeService)ÚmakePersonalServerFactoryÚ_AddHeadersResource)ÚDummyRequest)Ú	CGIScript)ÚWSGIResourcec                   @   sì   e Zd ZdZdd„ Zdd„ Zdd„ Ze e	¡s4de_
d	d
„ Zdd„ Zdd„ Zdd„ Zdd„ Ze e	¡slde_
dd„ Ze e	¡s„de_
dd„ Zdd„ Zdd„ Zdd„ Zdd„ Zedƒd k	r¾d!e_
d"d#„ Zedƒd krØd$e_
d%d&„ Zd'd(„ Zd S ))ÚServiceTestszD
    Tests for the service creation APIs in L{twisted.web.tap}.
    c                 C   s:   t |  ¡ ƒ}| ¡  tƒ }| d|jg¡ |d }||fS )aƒ  
        Helper for the I{--path} tests which creates a directory and creates
        an L{Options} object which uses that directory as its static
        filesystem root.

        @return: A two-tuple of a L{FilePath} referring to the directory and
            the value associated with the C{'root'} key in the L{Options}
            instance after parsing a I{--path} option.
        ú--pathÚroot)r   ÚmktempÚmakedirsr   ÚparseOptionsÚpath)Úselfr!   Úoptionsr   © r$   ú;/usr/lib/python3/dist-packages/twisted/web/test/test_tap.pyÚ_pathOption'   s    
zServiceTests._pathOptionc                 C   s,   |   ¡ \}}|  |t¡ |  |j|j¡ dS )zŠ
        The I{--path} option causes L{Options} to create a root resource
        which serves responses from the specified path.
        N)r&   ÚassertIsInstancer   ÚassertEqualr!   ©r"   r!   r   r$   r$   r%   Ú	test_path9   s    zServiceTests.test_pathc                 C   s´   t |  ¡ ƒ}| ¡  |  ¡ }tƒ }| dd| d|jg¡ t|ƒ}| ¡  |  |j	¡ |  
|jd jjt¡ |  |jd jjj|j¡ |  tj |¡¡ |  t t |¡j¡¡ dS )z¥
        The I{--path} option to L{makeService} causes it to return a service
        which will listen on the server address given by the I{--port} option.
        ú--portúunix:r   r   N)r   r   r   r   r    r!   r   ÚstartServiceÚ
addCleanupÚstopServicer'   ÚservicesÚfactoryÚresourcer   r(   Ú
assertTrueÚosÚexistsÚstatÚS_ISSOCKÚst_mode)r"   r!   Úportr#   Úservicer$   r$   r%   Útest_pathServerC   s    zServiceTests.test_pathServerz0The reactor does not support UNIX domain socketsc                 C   s4   |   ¡ \}}| d¡ d¡ |  | dd¡t¡ dS )z—
        The I{--path} option creates a root resource which serves a
        L{CGIScript} instance for any child with the C{".cgi"} extension.
        zfoo.cgió    N)r&   ÚchildÚ
setContentr'   ÚgetChildr   r)   r$   r$   r%   Útest_cgiProcessorZ   s    zServiceTests.test_cgiProcessorc                 C   s4   |   ¡ \}}| d¡ d¡ |  | dd¡t¡ dS )zš
        The I{--path} option creates a root resource which serves a
        L{PythonScript} instance for any child with the C{".epy"} extension.
        zfoo.epyr<   N)r&   r=   r>   r'   r?   r   r)   r$   r$   r%   Útest_epyProcessord   s    zServiceTests.test_epyProcessorc                 C   sT   |   ¡ \}}| d¡ d¡ | dd¡}|  |t¡ |  |jd¡ |  |jd¡ dS )zº
        The I{--path} option creates a root resource which serves the
        C{resource} global defined by the Python source in any child with
        the C{".rpy"} extension.
        zfoo.rpysN   from twisted.web.static import Data
resource = Data('content', 'major/minor')
NZcontentzmajor/minor)	r&   r=   r>   r?   r'   r   r(   ÚdataÚtype)r"   r!   r   r=   r$   r$   r%   Útest_rpyProcessorn   s    
ÿzServiceTests.test_rpyProcessorc                 C   sD   t tddƒƒ}t|ƒ}|  |t¡ |  |jt¡ |  |jj|¡ dS )z‡
        L{makePersonalServerFactory} returns a PB server factory which has
        as its root object a L{ResourcePublisher}.
        s   foo barz
text/plainN)	r   r   r   r'   r   r   r   ÚassertIdenticalÚsite)r"   rF   ZserverFactoryr$   r$   r%   Útest_makePersonalServerFactory~   s
    z+ServiceTests.test_makePersonalServerFactoryc                 C   sl   |   ¡ }tƒ }| dd| dg¡ t|ƒ}| ¡  |  |j¡ |  tj	 
|¡¡ |  t t |¡j¡¡ dS )z±
        The I{--personal} option to L{makeService} causes it to return a
        service which will listen on the server address given by the I{--port}
        option.
        r+   r,   ú
--personalN)r   r   r    r   r-   r.   r/   r3   r4   r!   r5   r6   r7   r8   )r"   r9   r#   r:   r$   r$   r%   Útest_personalServerŒ   s    z ServiceTests.test_personalServerc                 C   sH   t ƒ }| dg¡ tj tj dtj¡¡}|  |d d d 	|¡¡ dS )zÆ
        If the I{--port} option not specified but the I{--personal} option is,
        L{Options} defaults the port to C{UserDirectory.userSocketName} in the
        user's home directory.
        rH   ú~Úportsr   zunix:{}N)
r   r    r4   r!   Ú
expanduserÚjoinr   ZuserSocketNamer(   Úformat)r"   r#   r!   r$   r$   r%   Útest_defaultPersonalPath    s    ÿÿz%ServiceTests.test_defaultPersonalPathc                 C   s8   t ƒ }| g ¡ |  t |d d d¡dd… d¡ dS )zl
        If the I{--port} option is not specified, L{Options} defaults the port
        to C{8080}.
        rK   r   Né   )ZTCP)i  N)r   r    r(   r   Z_parseServer©r"   r#   r$   r$   r%   Útest_defaultPort²   s    
þzServiceTests.test_defaultPortc                 C   sD   t ƒ }| ddddg¡ |  d|d d ¡ |  d|d d ¡ d	S )
zQ
        If the I{--http} option is given twice, there are two listeners
        z--listenztcp:8001ztcp:8002Z8001rK   r   Z8002é   N©r   r    ZassertInrQ   r$   r$   r%   Útest_twoPorts¾   s    zServiceTests.test_twoPortsc                 C   sª   t ƒ }| dtd g¡ |d }|  |t¡ |  |jt¡ |  t|j	t
ƒ¡ |  |jt¡ |  |j	j¡ t d¡ |  |j	j¡ |  |j	j¡ t d¡ |  |j	j¡ dS )zÁ
        The I{--wsgi} option takes the fully-qualifed Python name of a WSGI
        application object and creates a L{WSGIResource} at the root which
        serves that application.
        ú--wsgiz.applicationr   ZstartupZshutdownN)r   r    Ú__name__r3   r   rE   Z_reactorr   Ú
isinstanceZ_threadpoolr	   Z_applicationÚapplicationZassertFalseZstartedZfireSystemEventZjoined)r"   r#   r   r$   r$   r%   Ú	test_wsgiÈ   s    

zServiceTests.test_wsgic                 C   sF   t ƒ }td dfD ].}|  t|jd|g¡}|  t|ƒd|f ¡ qdS )zn
        If I{--wsgi} is given an invalid name, L{Options.parseOptions}
        raises L{UsageError}.
        z.nosuchthingzfoo.rV   zNo such WSGI application: %rN)r   rW   ÚassertRaisesr
   r    r(   Ústr)r"   r#   ÚnameÚexcr$   r$   r%   Útest_invalidApplicationß   s      ÿ
ÿz$ServiceTests.test_invalidApplicationc                 C   s.   t ƒ }|  t|jdg¡}|  d|jd ¡ dS )zp
        An L{UsageError} is raised when C{https} is requested but there is no
        support for SSL.
        ú--https=443zSSL support not installedr   N)r   r[   r
   r    r(   Úargs)r"   r#   Z	exceptionr$   r$   r%   Útest_HTTPSFailureOnMissingSSLì   s      ÿz*ServiceTests.test_HTTPSFailureOnMissingSSLzOpenSSL.SSLNzSSL module is available.c                 C   s>   t ƒ }| dg¡ |  d|d d ¡ |  d|d d ¡ dS )zM
        When SSL support is present, it accepts the --https option.
        r`   ZsslrK   r   Z443NrT   rQ   r$   r$   r%   Ú test_HTTPSAcceptedOnAvailableSSLü   s    z-ServiceTests.test_HTTPSAcceptedOnAvailableSSLzSSL module is not available.c                 C   s0   t ƒ }| ddddg¡ |  |d ddg¡ dS )zE
        When --add-header is specific, the value is parsed.
        ú--add-headerúK1: V1úK2: V2ZextraHeaders©ÚK1ÚV1©ÚK2ÚV2N)r   r    r(   rQ   r$   r$   r%   Útest_add_header_parsing  s
    
ÿz$ServiceTests.test_add_header_parsingc                 C   s`   t ƒ }| ddddg¡ t|ƒ}|jd jj}|  |t¡ |  |j	ddg¡ |  |j
tj¡ dS )zj
        When --add-header is specified, the resource is a composition that adds
        headers.
        rd   re   rf   r   rg   rj   N)r   r    r   r0   r1   r2   r'   r   r(   Z_headersZ_originalResourcer   ÚTest)r"   r#   r:   r2   r$   r$   r%   Útest_add_header_resource  s    
ÿz%ServiceTests.test_add_header_resource)rW   Ú
__module__Ú__qualname__Ú__doc__r&   r*   r;   r   Z
providedByr   Úskipr@   rA   rD   rG   rI   rO   rR   rU   rZ   r_   rb   r   rc   rm   ro   r$   r$   r$   r%   r   #   s>   

ÿ


ÿ
ÿ
r   c                   @   s   e Zd Zdd„ ZdS )ÚAddHeadersResourceTestsc                 C   sZ   t t ¡ dddgƒ}tg ƒ}| d|¡ |  |j d¡ddg¡ |  |j d¡d	g¡ d
S )zc
        When getChildWithDefault is invoked, it adds the headers to the
        response.
        rg   rj   )rh   ÚV3Ú rh   ri   ru   rk   rl   N)r   r   rn   r   ZgetChildWithDefaultr(   ZresponseHeadersZgetRawHeaders)r"   r2   Zrequestr$   r$   r%   Útest_getChildWithDefault(  s     ÿ
 ÿz0AddHeadersResourceTests.test_getChildWithDefaultN)rW   rp   rq   rw   r$   r$   r$   r%   rt   '  s   rt   )2rr   Z
__future__r   r   r4   r6   Ztwisted.internetr   r   Ztwisted.internet.interfacesr   Ztwisted.python.filepathr   Ztwisted.python.reflectr   Ztwisted.python.threadpoolr	   Ztwisted.python.usager
   Ztwisted.spread.pbr   Ztwisted.trial.unittestr   Ztwisted.webr   Ztwisted.web.distribr   r   Ztwisted.web.scriptr   Ztwisted.web.serverr   Ztwisted.web.staticr   r   Ztwisted.web.tapr   r   r   r   Ztwisted.web.test.requesthelperr   Ztwisted.web.twcgir   Ztwisted.web.wsgir   ÚobjectrY   r   rt   r$   r$   r$   r%   Ú<module>   s4     