o
    Óó·iRF  ã                   @   sb  d Z ddlmZ ddlmZ zddlZW n ey   dZY nw e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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mZm Z m!Z! ddl"m#Z# ddl$m%Z% ddl&m'Z'm(Z( G dd„ de j)ƒZ*G dd„ dej+ƒZ+G dd„ de,ƒZ-G dd„ deƒZ.G dd„ dƒZ/G dd„ deƒZ0dS )z#
Tests for L{twisted.web.distrib}.
é    )Úabspath)ÚparseStringN)ÚskipIf)ÚverifyObject)ÚdeferÚreactor)ÚglobalLogPublisher)ÚfailureÚfilepath)Úpb©Ú
SIZE_LIMIT)Úproto_helpers)ÚTestCase)ÚclientÚdistribÚresourceÚserverÚstatic)ÚHeaders)Ú_render)ÚDummyChannelÚDummyRequestc                   @   s   e Zd ZdS )ÚMySiteN)Ú__name__Ú
__module__Ú__qualname__© r   r   úcC:\Users\psant\Downloads\PAF backend\school\venv\Lib\site-packages\twisted/web/test/test_distrib.pyr   #   s    r   c                   @   s   e Zd ZdZdZdd„ ZdS )ÚPBServerFactoryzÅ
    A PB server factory which keeps track of the most recent protocol it
    created.

    @ivar proto: L{None} or the L{Broker} instance most recently returned
        from C{buildProtocol}.
    Nc                 C   s   t j | |¡| _| jS ©N)r   r   ÚbuildProtocolÚproto)ÚselfÚaddrr   r   r   r!   2   s   zPBServerFactory.buildProtocol)r   r   r   Ú__doc__r"   r!   r   r   r   r   r   '   s    r   c                   @   s   e Zd ZdZdS )ÚArbitraryErrorz%
    An exception for this test.
    N)r   r   r   r%   r   r   r   r   r&   7   s    r&   c                   @   s„   e Zd ZdZdZdZdZdd„ Zdd„ Zdd„ Z	dd	„ Z
d
d„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ ZdS )ÚDistribTestsNc                    sØ   t  ¡ t  ¡ g‰ | jdur| jjdur| jj ‡ fdd„¡ nˆ d  d¡ | jdurF| jjdurF| jjj ‡ fdd„¡ | jjjj	 
¡  nˆ d  d¡ | jdurZˆ  | j ¡ ¡ | jdurgˆ  | j ¡ ¡ t  ˆ ¡S )z‹
        Clean up all the event sources left behind by either directly by
        test methods or indirectly via some distrib API.
        Nc                      ó   ˆ d   d ¡S ©Nr   ©Úcallbackr   ©Údlr   r   Ú<lambda>J   ó    z'DistribTests.tearDown.<locals>.<lambda>r   c                      r(   )Né   r*   r   r,   r   r   r.   N   r/   r0   )r   ÚDeferredÚf1r"   ÚnotifyOnDisconnectr+   ÚsubZ	publisherZbrokerÚ	transportZloseConnectionÚport1ÚappendÚstopListeningÚport2ZgatherResults©r#   r   r,   r   ÚtearDownC   s   


zDistribTests.tearDownc                 C   sÚ   t  ¡ }| dt dd¡¡ t |¡}tt 	|¡ƒ| _
t d| j
¡| _t d| j ¡ j¡| _t  ¡ }| d| j¡ t|ƒ}t d|¡| _t t¡}d| j ¡ j› d�}| d	¡}| d
|¡}| tj¡ | | jd¡ |S )Ns   theres   rootz
text/plainr   ú	127.0.0.1s   herezhttp://127.0.0.1:z/here/thereÚasciió   GET)r   ÚResourceÚputChildr   ZDatar   ÚSiter   r   ÚResourcePublisherr2   r   Ú	listenTCPr6   ÚResourceSubscriptionÚgetHostÚportr4   r   r9   r   ÚAgentÚencodeÚrequestÚaddCallbackÚreadBodyÚassertEqual)r#   Zr1Zsite1Zr2Úf2ÚagentÚurlÚdr   r   r   ÚtestDistribX   s"   


zDistribTests.testDistribc                 C   s¢   t  ¡ }| d|¡ t |¡}tt |¡ƒ | _}t	j
d|dd�}|  |j¡ | ¡ }t |j|j¡ | _}t |¡}t	j
d|dd�}	|  |	j¡ |	 ¡ }
|	|
fS )zû
        Set up a resource on a distrib site using L{ResourcePublisher}.

        @param child: The resource to publish using distrib.

        @return: A tuple consisting of the host and port on which to contact
            the created site.
        s   childr   r<   )Z	interfaceN)r   r?   r@   r   rA   r   r   rB   r2   r   rC   Z
addCleanupr8   rE   rD   ÚhostrF   r4   )r#   ÚchildZdistribRootZdistribSiteZdistribFactoryZdistribPortr$   ZmainRootZmainSiteÚmainPortÚmainAddrr   r   r   Ú_setupDistribServerl   s   	

ÿ
z DistribTests._setupDistribServerc                 K   s\   |   |¡\}}t t¡}d|j› d|j› d�}| d¡}|jd|fi |¤Ž}| tj	¡ |S )a¡  
        Set up a resource on a distrib site using L{ResourcePublisher} and
        then retrieve it from a L{ResourceSubscription} via an HTTP client.

        @param child: The resource to publish using distrib.
        @param **kwargs: Extra keyword arguments to pass to L{Agent.request} when
            requesting the resource.

        @return: A L{Deferred} which fires with the result of the request.
        úhttp://ú:ú/childr=   r>   N)
rV   r   rG   r   rR   rF   rH   rI   rJ   rK   )r#   rS   ÚkwargsrT   rU   rN   rO   rP   r   r   r   Ú_requestTest‡   s   

zDistribTests._requestTestc                 K   s^   |   |¡\}}d|j› d|j› d�}| d¡}t t¡jd|fi |¤Ž}dd„ }| |¡ |S )	a;  
        Set up a resource on a distrib site using L{ResourcePublisher} and
        then retrieve it from a L{ResourceSubscription} via an HTTP client.

        @param child: The resource to publish using distrib.
        @param **kwargs: Extra keyword arguments to pass to L{Agent.request} when
            requesting the resource.

        @return: A L{Deferred} which fires with a tuple consisting of a
            L{twisted.test.proto_helpers.AccumulatingProtocol} containing the
            body of the response and an L{IResponse} with the response itself.
        rW   rX   rY   r=   r>   c                    s8   t  ¡ ‰ ˆ ˆ ¡ t ¡  }ˆ _| ‡ ‡fdd„¡ |S )Nc                    s   ˆ ˆfS r    r   )Ú_©ÚprotocolÚresponser   r   r.   ±   s    zGDistribTests._requestAgentTest.<locals>.cbCollectBody.<locals>.<lambda>)r   ZAccumulatingProtocolZdeliverBodyr   r1   ZclosedDeferredrJ   )r_   rP   r   r]   r   ÚcbCollectBody­   s
   
z5DistribTests._requestAgentTest.<locals>.cbCollectBodyN)	rV   rR   rF   rH   r   rG   r   rI   rJ   )r#   rS   rZ   rT   rU   rO   rP   r`   r   r   r   Ú_requestAgentTestš   s   

zDistribTests._requestAgentTestc                    s|   i ‰t  ¡ ‰t ˆ¡ dg‰G ‡‡fdd„dtjƒ}‡‡‡fdd„‰ ˆj|ƒ tddgiƒd�}‡ ‡‡fd	d
„}| |¡ |S )z†
        The request headers are available on the request object passed to a
        distributed resource's C{render} method.
        Nc                       s   e Zd Z‡ ‡fdd„ZdS )z>DistribTests.test_requestHeaders.<locals>.ReportRequestHeadersc                    s    |ˆ d< ˆ  t|j ¡ ƒ¡ dS )Nr   ó    )ÚupdateÚdictÚrequestHeadersZgetAllRawHeaders©r#   rI   ©Úreqre   r   r   ÚrenderÂ   s   zEDistribTests.test_requestHeaders.<locals>.ReportRequestHeaders.renderN©r   r   r   ri   r   rg   r   r   ÚReportRequestHeadersÁ   s    rk   c                     sD   dd„ ˆ D ƒ} ˆ  d| ¡ ˆ  d| ¡ ˆ  ˆd | ¡ t ˆ ¡ d S )Nc                 S   s   g | ]}|d  ‘qS )Ú
log_formatr   )Ú.0Úer   r   r   Ú
<listcomp>È   s    zHDistribTests.test_requestHeaders.<locals>.check_logs.<locals>.<listcomp>zconnected to publisherz3could not connect to distributed web service: {msg}r   )ÚassertInr   ZremoveObserver)Zmsgs)ÚlogObserverrh   r#   r   r   Ú
check_logsÇ   s
   z4DistribTests.test_requestHeaders.<locals>.check_logsZfooÚbar)Úheadersc                    s$   ˆj j ˆ ¡ ˆ ˆd dg¡ d S )Ns   Foos   bar)r2   r"   r3   rL   ©Úresult)rr   re   r#   r   r   ÚcbRequestedÒ   s   z5DistribTests.test_requestHeaders.<locals>.cbRequested)	r   ÚEventLoggingObserverr   ZaddObserverr   r?   r[   r   rJ   )r#   rk   rI   rw   r   )rr   rq   rh   re   r#   r   Útest_requestHeaders·   s   
ÿ
z DistribTests.test_requestHeadersc                    ó8   G dd„ dt jƒ}ˆ  |ƒ ¡}‡ fdd„}| |¡ |S )z�
        The response code can be set by the request object passed to a
        distributed resource's C{render} method.
        c                   @   ó   e Zd Zdd„ ZdS )z>DistribTests.test_requestResponseCode.<locals>.SetResponseCodec                 S   s   |  d¡ dS )NéÈ   Ú ©ZsetResponseCoderf   r   r   r   ri   à   s   
zEDistribTests.test_requestResponseCode.<locals>.SetResponseCode.renderNrj   r   r   r   r   ÚSetResponseCodeß   ó    r   c                    ó:   ˆ   | d jd¡ ˆ   | d jd¡ ˆ   | d jd¡ d S )Nr   rb   r0   r|   s   OK©rL   ÚdataÚcodeÚphraseru   r:   r   r   rw   æ   ó   z:DistribTests.test_requestResponseCode.<locals>.cbRequestedN©r   r?   ra   rJ   ©r#   r   rI   rw   r   r:   r   Útest_requestResponseCodeÙ   ó
   
z%DistribTests.test_requestResponseCodec                    rz   )z�
        The response code and message can be set by the request object passed to
        a distributed resource's C{render} method.
        c                   @   r{   )zEDistribTests.test_requestResponseCodeMessage.<locals>.SetResponseCodec                 S   s   |  dd¡ dS )Nr|   ó   some-messager}   r~   rf   r   r   r   ri   õ   s   zLDistribTests.test_requestResponseCodeMessage.<locals>.SetResponseCode.renderNrj   r   r   r   r   r   ô   r€   r   c                    r�   )Nr   rb   r0   r|   r‹   r‚   ru   r:   r   r   rw   û   r†   zADistribTests.test_requestResponseCodeMessage.<locals>.cbRequestedNr‡   rˆ   r   r:   r   Útest_requestResponseCodeMessageî   rŠ   z,DistribTests.test_requestResponseCodeMessagec                 C   ó8   G dd„ dt jƒ}|  |ƒ ¡}| | jdt d ¡ |S )zÞ
        If a string longer than the Banana size limit is passed to the
        L{distrib.Request} passed to the remote resource, it is broken into
        smaller strings to be transported over the PB connection.
        c                   @   r{   )z0DistribTests.test_largeWrite.<locals>.LargeWritec                 S   s    |  dt d ¡ | ¡  tjS ©Nó   xó   y)Úwriter   Úfinishr   ZNOT_DONE_YETrf   r   r   r   ri     s   z7DistribTests.test_largeWrite.<locals>.LargeWrite.renderNrj   r   r   r   r   Ú
LargeWrite
  r€   r“   r�   r�   N©r   r?   r[   rJ   rL   r   )r#   r“   rI   r   r   r   Útest_largeWrite  s   zDistribTests.test_largeWritec                 C   r�   )z 
        Like L{test_largeWrite}, but for the case where C{render} returns a
        long string rather than explicitly passing it to L{Request.write}.
        c                   @   r{   )z2DistribTests.test_largeReturn.<locals>.LargeReturnc                 S   s   dt  d S rŽ   r   rf   r   r   r   ri     s   z9DistribTests.test_largeReturn.<locals>.LargeReturn.renderNrj   r   r   r   r   ÚLargeReturn  r€   r–   r�   r�   Nr”   )r#   r–   rI   r   r   r   Útest_largeReturn  s   zDistribTests.test_largeReturnc                    sl   t t ¡ ƒ ˆ_}t d|¡ ˆ_}t d| 	¡ j
¡ ˆ_}tdgƒ‰ t|ˆ ƒ}‡ ‡fdd„}| |¡ |S )zz
        If there is an error issuing the request to the remote publisher, an
        error response is returned.
        r   r<   rb   c                    sL   ˆ  ˆ jd¡ ˆ tj¡}ˆ  t|ƒd¡ g d¢}ˆ  d |¡gˆ j¡ d S )Niô  r0   )
rb   s   <html>s:     <head><title>500 - Server Connection Lost</title></head>s     <body>s#       <h1>Server Connection Lost</h1>s¦       <p>Connection to distributed server lost:<pre>[Failure instance: Traceback from remote host -- twisted.spread.flavors.NoSuchMethod: No such method: remote_requests   ]</pre></p>s	     </body>s   </html>rb   ó   
)rL   ÚresponseCodeÚflushLoggedErrorsr   ZNoSuchMethodÚlenÚjoinÚwritten)ÚignoredÚerrorsÚexpected©rI   r#   r   r   Ú
cbRendered2  s
   z4DistribTests.test_connectionLost.<locals>.cbRenderedN)r   r   ZRootr2   r   rC   r6   r   rD   rE   rF   r4   r   r   rJ   )r#   ZserverFactoryZ
serverPortZsubscriptionrP   r¢   r   r¡   r   Útest_connectionLost"  s   

ÿ


z DistribTests.test_connectionLostc                 C   s`   t j | t¡}t tƒ ¡}tdgƒ}t 	|¡}| 
|¡ |  dt|ƒ¡ |  d|d d ¡ dS )zQ
        When a request fails, the string form of the failure is logged.
        rb   r0   zFailure instancer   rl   N)r   rx   ÚcreateWithCleanupr   r	   ÚFailurer&   r   r   ZIssueÚfailedÚassertEqualsr›   rp   )r#   rq   ÚfrI   Úissuer   r   r   Útest_logFailedN  s   ÿ


zDistribTests.test_logFailedc                 C   sf   t j | t¡}tƒ }t |¡}t t	ƒ ¡}| 
|¡ |  t¡ |  dt|ƒ¡ |  |d d |¡ dS )zf
        When L{twisted.web.distrib.Request}'s fail is called, the failure
        is logged.
        r0   r   Zlog_failureN)r   rx   r¤   r   r&   r	   r¥   r   ÚRequestr   Zfailrš   r§   r›   ZassertIs)r#   rq   Úerrr¨   rh   r   r   r   Útest_requestFail]  s   ÿ


zDistribTests.test_requestFail)r   r   r   r6   r9   r4   r2   r;   rQ   rV   r[   ra   ry   r‰   rŒ   r•   r—   r£   rª   r­   r   r   r   r   r'   =   s$    ",r'   c                   @   s$   e Zd Zdd„ Zdd„ Zdd„ ZdS )Ú_PasswordDatabasec                 C   s
   || _ d S r    )Ú_users)r#   Zusersr   r   r   Ú__init__o  ó   
z_PasswordDatabase.__init__c                 C   s
   t | jƒS r    )Úiterr¯   r:   r   r   r   Úgetpwallr  r±   z_PasswordDatabase.getpwallc                 C   s&   | j D ]}|d |kr|  S qtƒ ‚r)   )r¯   ÚKeyError)r#   ÚusernameÚuserr   r   r   Úgetpwnamu  s
   
ÿz_PasswordDatabase.getpwnamN)r   r   r   r°   r³   r·   r   r   r   r   r®   n  s    r®   c                   @   sv   e Zd ZdZdd„ Zdd„ Zdeddfd	d
„Zdd„ Zdd„ Z	dd„ Z
dd„ Zdd„ Zdd„ Zee dƒdd„ ƒZdS )ÚUserDirectoryTestszj
    Tests for L{UserDirectory}, a resource for listing all user resources
    available on a system.
    c                 C   sT   ddddd|   ¡ df| _dddd	d
|   ¡ df| _t| j| jgƒ| _t | j¡| _d S )NÚaliceÚxé{   iÈ  zAlice,,,z/bin/shÚbobéê   i7  zBob,,,)Úmktempr¹   r¼   r®   Zdatabaser   ÚUserDirectoryÚ	directoryr:   r   r   r   ÚsetUp‚  s   zUserDirectoryTests.setUpc                 C   s   |   ttj| jƒ¡ dS )zK
        L{UserDirectory} instances provide L{resource.IResource}.
        N)Ú
assertTruer   r   Z	IResourcerÀ   r:   r   r   r   Útest_interfaceˆ  s   z!UserDirectoryTests.test_interfaceÚnameÚreturnNc                 Ã   s@   �t |gƒ}| j ||¡}t||ƒ}|I dH  |  |jd¡ dS )zr
        Verify that requesting the C{name} child of C{self.directory} results
        in a 404 response.
        Ni”  )r   rÀ   ÚgetChildr   rL   r™   )r#   rÄ   rI   rv   rP   r   r   r   Ú_404TestŽ  s   €


zUserDirectoryTests._404Testc                 Ã   ó   �|   d¡I dH  dS )z­
        L{UserDirectory.getChild} returns a resource which renders a 404
        response when passed a string which does not correspond to any known
        user.
        s   carolN©rÇ   r:   r   r   r   Útest_getInvalidUser™  ó   €z&UserDirectoryTests.test_getInvalidUserc                 Ã   rÈ   )zÞ
        L{UserDirectory.getChild} returns a resource which renders a 404
        response when passed a string which corresponds to a known user who has
        neither a user directory nor a user distrib socket.
        s   aliceNrÉ   r:   r   r   r   Útest_getUserWithoutResource¡  rË   z.UserDirectoryTests.test_getUserWithoutResourcec                 C   s\   t  | jd ¡}| d¡}| ¡  tdgƒ}| j d|¡}|  |t	j
¡ |  |j|j¡ dS )z¹
        L{UserDirectory.getChild} returns a L{static.File} instance when passed
        the name of a user with a home directory containing a I{public_html}
        directory.
        éþÿÿÿÚpublic_htmlr¼   s   bobN)r
   ÚFilePathr¼   rS   Úmakedirsr   rÀ   rÆ   ÚassertIsInstancer   ÚFilerL   Úpath)r#   ÚhomerÎ   rI   rv   r   r   r   Útest_getPublicHTMLChild©  s   

z*UserDirectoryTests.test_getPublicHTMLChildc                 C   sn   t  | jd ¡}| ¡  | d¡}tdgƒ}| j d|¡}|  |t	j
¡ |  |jd¡ |  t|jƒ|j¡ dS )zà
        L{UserDirectory.getChild} returns a L{ResourceSubscription} instance
        when passed the name of a user suffixed with C{".twistd"} who has a
        home directory containing a I{.twistd-web-pb} socket.
        rÍ   ú.twistd-web-pbr¼   s
   bob.twistdÚunixN)r
   rÏ   r¼   rÐ   rS   r   rÀ   rÆ   rÑ   r   rD   rL   rR   r   rF   rÓ   )r#   rÔ   ÚwebrI   rv   r   r   r   Útest_getDistribChild·  s   

z'UserDirectoryTests.test_getDistribChildc                 C   s(   t dgƒ}d|_|  tj| jj|¡ dS )zr
        L{UserDirectory.render} raises L{UnsupportedMethod} in response to a
        non-I{GET} request.
        r}   ÚPOSTN)r   ÚmethodÚassertRaisesr   ZUnsupportedMethodrÀ   ri   rf   r   r   r   Útest_invalidMethodÆ  s   
z%UserDirectoryTests.test_invalidMethodc                    sx   t  ˆjd ¡ d¡}| ¡  t  ˆjd ¡}| ¡  | d¡ d¡ tdgƒ‰ tˆj	ˆ ƒ}‡ ‡fdd„}| 
|¡ |S )	z}
        L{UserDirectory} renders a list of links to available user content
        in response to a I{GET} request.
        rÍ   rÎ   rÖ   rb   r}   c                    sŽ   t d ˆ j¡ƒ}| d¡\}}ˆ |jjd¡ ˆ |j d¡d¡ ˆ |jjjd¡ ˆ |jjd¡ ˆ |j d¡d¡ ˆ |jjjd¡ d S )	Nrb   ÚliÚaÚhrefzalice/zAlice (file)zbob.twistd/zBob (twistd))	r   rœ   r�   ZgetElementsByTagNamerL   Z
firstChildZtagNameÚgetAttributerƒ   )rž   Údocumentr¹   r¼   r¡   r   r   r¢   à  s   z2UserDirectoryTests.test_render.<locals>.cbRenderedN)r
   rÏ   r¹   rS   rÐ   r¼   Z
setContentr   r   rÀ   rJ   )r#   rÎ   rØ   rv   r¢   r   r¡   r   Útest_renderÏ  s   

zUserDirectoryTests.test_renderzpwd module requiredc                 C   s   t  ¡ }|  |jt¡ dS )z„
        If L{UserDirectory} is instantiated with no arguments, it uses the
        L{pwd} module as its password database.
        N)r   r¿   ZassertIdenticalÚ_pwdÚpwd)r#   rÀ   r   r   r   Útest_passwordDatabaseï  s   z(UserDirectoryTests.test_passwordDatabase)r   r   r   r%   rÁ   rÃ   ÚbytesrÇ   rÊ   rÌ   rÕ   rÙ   rÝ   rã   r   rå   ræ   r   r   r   r   r¸   |  s    	
 r¸   )1r%   Úos.pathr   Zxml.dom.minidomr   rå   rä   ÚImportErrorZunittestr   Zzope.interface.verifyr   Ztwisted.internetr   r   Ztwisted.loggerr   Ztwisted.pythonr	   r
   Ztwisted.spreadr   Ztwisted.spread.bananar   Ztwisted.testr   Ztwisted.trial.unittestr   Ztwisted.webr   r   r   r   r   Ztwisted.web.http_headersr   Ztwisted.web.test._utilr   Ztwisted.web.test.requesthelperr   r   rA   r   r   Ú	Exceptionr&   r'   r®   r¸   r   r   r   r   Ú<module>   s<   ÿ  3