
    YfRF                        d Z ddlmZ ddlmZ 	 ddlZeZn# e$ r dZY nw xY w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e j)                  Z* G d dej+                  Z+ G d de,          Z- G d de          Z. G d d          Z/ G 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                       e Zd ZdS )MySiteN)__name__
__module____qualname__     O/var/www/html/env/lib/python3.11/site-packages/twisted/web/test/test_distrib.pyr   r   #   s        Dr    r   c                       e Zd ZdZdZ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                 Z    t           j                            | |          | _        | j        S N)r   r#   buildProtocolproto)selfaddrs     r!   r&   zPBServerFactory.buildProtocol2   s$    '55dDAA
zr    )r   r   r   __doc__r'   r&   r   r    r!   r#   r#   '   s4          E    r    r#   c                       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    r,   c                   l    e Zd ZdZdZdZdZd Zd Zd Z	d Z
d Zd Zd Zd	 Zd
 Zd Zd Zd Zd ZdS )DistribTestsNc                    t          j                    t          j                    g| j        /| j        j        #| j        j                            fd           nd                             d           | j        \| j        j        P| j        j        j                            fd           | j        j        j        j	        
                                 nd                             d           | j        ,                    | j                                                   | j        ,                    | j                                                   t          j                  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   callbackdls   r!   <lambda>z'DistribTests.tearDown.<locals>.<lambda>J   s    RU^^D5I5I r    r   c                  :     d                              d           S )N   r2   r4   s   r!   r6   z'DistribTests.tearDown.<locals>.<lambda>N   s    APTAUAU r    r8   )r   Deferredf1r'   notifyOnDisconnectr3   sub	publisherbroker	transportloseConnectionport1appendstopListeningport2gatherResults)r(   r5   s    @r!   tearDownzDistribTests.tearDownC   s:   
 n 0 01747=#<GM,,-I-I-I-IJJJJqENN4   8DH$6$BH%889U9U9U9UVVVH%/>>@@@@qENN4   :!IIdj..00111:!IIdj..00111"2&&&r    c                    t          j                    }|                    dt          j        dd                     t          j        |          }t          t          j	        |                    | _
        t          j        d| j
                  | _        t          j        d| j                                        j                  | _        t          j                    }|                    d| j                   t%          |          }t          j        d|          | _        t)          j        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   Datar   Siter#   r   ResourcePublisherr:   r   	listenTCPrA   ResourceSubscriptiongetHostportr<   r   rD   r   AgentencoderequestaddCallbackreadBodyassertEqual)r(   r1site1r2f2agenturlds           r!   testDistribzDistribTests.testDistribX   sY     
Hfk'<@@AAAB!'";E"B"BCC&q$'22
/TZ=O=O=Q=Q=VWW  
GTX&&&BZZ&q"--
W%%H$*"4"4"6"6";HHHjj!!MM&#&&	fo&&&	d&000r    c                 \   t          j                    }|                    d|           t          j        |          }t          t          j        |                    x| _        }t          j
        d|d          }|                     |j                   |                                }t          j        |j        |j                  x| _        }t          j        |          }t          j
        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   rH   )	interface)r   rK   rL   r   rN   r#   r   rO   r:   r   rP   
addCleanuprC   rR   rQ   hostrS   r<   )r(   childdistribRootdistribSitedistribFactorydistribPortr)   mainRootmainSitemainPortmainAddrs              r!   _setupDistribServerz DistribTests._setupDistribServerl   s    '))Xu---k+..#2%k22$
 $
 	
. '>[QQQ1222""$$%:49diPPP8;x(($QKHHH.///##%%!!r    c                    |                      |          \  }}t          j        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://:/childrI   rJ   )
ro   r   rT   r   re   rS   rU   rV   rW   rX   )r(   rf   kwargsrm   rn   r^   r_   r`   s           r!   _requestTestzDistribTests._requestTest   s     "55e<<(W%%======jj!!EM&#0000	fo&&&r    c                    |                      |          \  }}d|j         d|j         d}|                    d          } t	          j        t                    j        d|fi |}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.
        rq   rr   rs   rI   rJ   c                      t          j                                                    t          j                    x}_        |                     fd           |S )Nc                     fS r%   r   )_protocolresponses    r!   r6   zGDistribTests._requestAgentTest.<locals>.cbCollectBody.<locals>.<lambda>   s    Xx$8 r    )r   AccumulatingProtocoldeliverBodyr   r9   closedDeferredrW   )r{   r`   rz   s   ` @r!   cbCollectBodyz5DistribTests._requestAgentTest.<locals>.cbCollectBody   s_    $9;;H  ****/.*:*::A'MM88888999Hr    )	ro   re   rS   rU   r   rT   r   rV   rW   )r(   rf   rt   rm   rn   r_   r`   r   s           r!   _requestAgentTestzDistribTests._requestAgentTest   s     "55e<<(======jj!!)FL!!)&#@@@@	 	 	 	
m$$$r    c                 B    i t          j                    t          j                   dg G fddt          j                  } fd                      |            t          ddgi                    } fd}|                    |           |S )	z
        The request headers are available on the request object passed to a
        distributed resource's C{render} method.
        Nc                       e Zd Z fdZdS )>DistribTests.test_requestHeaders.<locals>.ReportRequestHeadersc                     |d<                        t          |j                                                             dS )Nr   r    )updatedictrequestHeadersgetAllRawHeaders)r(   rV   reqr   s     r!   renderzEDistribTests.test_requestHeaders.<locals>.ReportRequestHeaders.render   s<     A%%d7+A+R+R+T+T&U&UVVVsr    Nr   r   r   r   )r   r   s   r!   ReportRequestHeadersr      s3               r    r   c                      d D             }                      d|                                 d|                                 d         |            t          j                   d S )Nc                     g | ]
}|d          S )
log_formatr   ).0es     r!   
<listcomp>zHDistribTests.test_requestHeaders.<locals>.check_logs.<locals>.<listcomp>   s    999AlO999r    zconnected to publisherz3could not connect to distributed web service: {msg}r   )assertInr	   removeObserver)msgslogObserverr   r(   s    r!   
check_logsz4DistribTests.test_requestHeaders.<locals>.check_logs   sp    99[999DMM2D999MMOQUVVVMM#a&$'''-k:::::r    foobar)headersc                     j         j                                                           d         dg           d S )Ns   Foos   bar)r:   r'   r;   rY   )resultr   r   r(   s    r!   cbRequestedz5DistribTests.test_requestHeaders.<locals>.cbRequested   s>    GM,,Z888^F3fX>>>>>r    )	r   EventLoggingObserverr	   addObserverr   rK   ru   r   rW   )r(   r   rV   r   r   r   r   r   s   `   @@@@r!   test_requestHeadersz DistribTests.test_requestHeaders   s
   
 #8::&{333f	 	 	 	 	 	 	 	8#4 	 	 		; 	; 	; 	; 	; 	; 	; ##  ""GUUG4D,E,E $ 
 
	? 	? 	? 	? 	? 	? 	? 	K(((r    c                       G d dt           j                  }                      |                      } f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 ZdS )>DistribTests.test_requestResponseCode.<locals>.SetResponseCodec                 0    |                     d           dS )N    setResponseCoder(   rV   s     r!   r   zEDistribTests.test_requestResponseCode.<locals>.SetResponseCode.render   s    '',,,rr    Nr   r   r    r!   SetResponseCoder      #            r    r   c                                          | d         j        d                                | d         j        d                                | d         j        d           d S )Nr   r    r8   r   s   OKrY   datacodephraser   r(   s    r!   r   z:DistribTests.test_requestResponseCode.<locals>.cbRequested   s^    VAY^S111VAY^S111VAY-u55555r    r   rK   r   rW   r(   r   rV   r   s   `   r!   test_requestResponseCodez%DistribTests.test_requestResponseCode   s    	 	 	 	 	h/ 	 	 	
 (():):;;	6 	6 	6 	6 	6
 	K(((r    c                       G d dt           j                  }                      |                      } fd}|                    |           |S )z
        The response code and message can be set by the request object passed to
        a distributed resource's C{render} method.
        c                       e Zd Zd ZdS )EDistribTests.test_requestResponseCodeMessage.<locals>.SetResponseCodec                 2    |                     dd           dS )Nr      some-messager   r   r   s     r!   r   zLDistribTests.test_requestResponseCodeMessage.<locals>.SetResponseCode.render   s    ''_===rr    Nr   r   r    r!   r   r      r   r    r   c                                          | d         j        d                                | d         j        d                                | d         j        d           d S )Nr   r    r8   r   r   r   r   s    r!   r   zADistribTests.test_requestResponseCodeMessage.<locals>.cbRequested   s^    VAY^S111VAY^S111VAY-?????r    r   r   s   `   r!   test_requestResponseCodeMessagez,DistribTests.test_requestResponseCodeMessage   s    	 	 	 	 	h/ 	 	 	
 (():):;;	@ 	@ 	@ 	@ 	@
 	K(((r    c                      G d dt           j                  }|                      |                      }|                    | j        dt
          z  dz              |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                       e Zd Zd ZdS )0DistribTests.test_largeWrite.<locals>.LargeWritec                     |                     dt          z  dz              |                                 t          j        S N   x   y)writer   finishr   NOT_DONE_YETr   s     r!   r   z7DistribTests.test_largeWrite.<locals>.LargeWrite.render  s7    dZ/$6777   **r    Nr   r   r    r!   
LargeWriter   
  s#        + + + + +r    r   r   r   r   rK   ru   rW   rY   r   )r(   r   rV   s      r!   test_largeWritezDistribTests.test_largeWrite  sr    	+ 	+ 	+ 	+ 	+* 	+ 	+ 	+ ##JJLL11D,dZ.?$.FGGGr    c                      G d dt           j                  }|                      |                      }|                    | j        dt
          z  dz              |S )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                       e Zd Zd ZdS )2DistribTests.test_largeReturn.<locals>.LargeReturnc                     dt           z  dz   S r   r   r   s     r!   r   z9DistribTests.test_largeReturn.<locals>.LargeReturn.render  s    j(4//r    Nr   r   r    r!   LargeReturnr     s#        0 0 0 0 0r    r   r   r   r   )r(   r   rV   s      r!   test_largeReturnzDistribTests.test_largeReturn  sr    	0 	0 	0 	0 	0(+ 	0 	0 	0 ##KKMM22D,dZ.?$.FGGGr    c                 l    t          t          j                              x _        }t	          j        d|          x _        }t          j        d|	                                j
                  x _        }t          dg          t          |          } fd}|                    |           |S )zz
        If there is an error issuing the request to the remote publisher, an
        error response is returned.
        r   rH   r    c                 (                        j        d                               t          j                  }                     t          |          d           g d}                     d                    |          gj                   d S )Ni  r8   )
r    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>r       
)rY   responseCodeflushLoggedErrorsr   NoSuchMethodlenjoinwritten)ignorederrorsexpectedrV   r(   s      r!   
cbRenderedz4DistribTests.test_connectionLost.<locals>.cbRendered2  s    W13777 ++BO<<FS[[!,,,  H  ejj223W_EEEEEr    )r#   r   Rootr:   r   rP   rA   r   rQ   rR   rS   r<   r   r   rW   )r(   serverFactory
serverPortsubscriptionr`   r   rV   s   `     @r!   test_connectionLostz DistribTests.test_connectionLost"  s     #2"'))"<"<<-")"3A}"E"EE
Z")">++--2#
 #
 	
< u%%L'**	F 	F 	F 	F 	F 	F2 	
j!!!r    c                    t           j                            | t                    }t	          j        t                                }t          dg          }t          j	        |          }|
                    |           |                     dt          |                     |                     d|d         d                    dS )zQ
        When a request fails, the string form of the failure is logged.
        r    r8   zFailure instancer   r   N)r   r   createWithCleanupr	   r
   Failurer,   r   r   IssuefailedassertEqualsr   r   )r(   r   frV   issues        r!   test_logFailedzDistribTests.test_logFailedN  s     $8JJ$
 
 ON,,--u%%g&&Q!S--...(+a.*FGGGGGr    c                    t           j                            | t                    }t	                      }t          j        |          }t          j        t                                }|
                    |           |                     t                     |                     dt          |                     |                     |d         d         |           dS )zf
        When L{twisted.web.distrib.Request}'s fail is called, the failure
        is logged.
        r8   r   log_failureN)r   r   r   r	   r,   r
   r   r   Requestr   failr   r   r   assertIs)r(   r   errr   r   s        r!   test_requestFailzDistribTests.test_requestFail]  s    
 $8JJ$
 
 OC  olnn--~...!S--...k!n]3Q77777r    )r   r   r   rA   rD   r<   r:   rF   ra   ro   ru   r   r   r   r   r   r   r   r   r   r   r    r!   r.   r.   =   s        EE
C	B' ' '*  (" " "6  &  :     D  *  *  "  * * *XH H H8 8 8 8 8r    r.   c                        e Zd Zd Zd Zd ZdS )_PasswordDatabasec                     || _         d S r%   )_users)r(   userss     r!   __init__z_PasswordDatabase.__init__o  s    r    c                 *    t          | j                  S r%   )iterr   r(   s    r!   getpwallz_PasswordDatabase.getpwallr  s    DK   r    c                 R    | j         D ]}|d         |k    r|c S t                      r1   )r   KeyError)r(   usernameusers      r!   getpwnamz_PasswordDatabase.getpwnamu  s:    K 	 	DAw("" #jjr    N)r   r   r   r   r   r   r   r    r!   r   r   n  sA          ! ! !    r    r   c                   ~    e Zd ZdZd Zd ZdeddfdZd Zd	 Z	d
 Z
d Zd Zd Z ee d          d             ZdS )UserDirectoryTestszj
    Tests for L{UserDirectory}, a resource for listing all user resources
    available on a system.
    c                    ddddd|                                  df| _        dddd	d
|                                  df| _        t          | j        | j        g          | _        t          j        | j                  | _        d S )Nalicex{   i  zAlice,,,z/bin/shbob   i7  zBob,,,)mktempr  r  r   databaser   UserDirectory	directoryr   s    r!   setUpzUserDirectoryTests.setUp  sn    sCj$++--S
3S(DKKMM9M)4:tx*@AA .t}==r    c                 j    |                      t          t          j        | j                             dS )zK
        L{UserDirectory} instances provide L{resource.IResource}.
        N)
assertTruer   r   	IResourcer  r   s    r!   test_interfacez!UserDirectoryTests.test_interface  s+     	X%7HHIIIIIr    namereturnNc                    K   t          |g          }| j                            ||          }t          ||          }| d{V  |                     |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   rY   r   )r(   r  rV   r   r`   s        r!   _404TestzUserDirectoryTests._404Test  sm      
 v&&((w77FG$$-s33333r    c                 @   K   |                      d           d{V  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   s    r!   test_getInvalidUserz&UserDirectoryTests.test_getInvalidUser  2       mmH%%%%%%%%%%%r    c                 @   K   |                      d           d{V  dS )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   s    r!   test_getUserWithoutResourcez.UserDirectoryTests.test_getUserWithoutResource  r  r    c                 l   t          j        | 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  rf   makedirsr   r  r  assertIsInstancer   FilerY   path)r(   homer  rV   r   s        r!   test_getPublicHTMLChildz*UserDirectoryTests.test_getPublicHTMLChild  s      "..jj//w''((99ffk222k&677777r    c                    t          j        | 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   rf   r   r  r  r!  r   rQ   rY   re   r   rS   r#  )r(   r$  webrV   r   s        r!   test_getDistribChildz'UserDirectoryTests.test_getDistribChild  s      "..jj)**w''((@@fg&BCCCf-----sx88888r    c                     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   UnsupportedMethodr  r   r   s     r!   test_invalidMethodz%UserDirectoryTests.test_invalidMethod  s@    
 t$$&2DN4I7SSSSSr    c                     t          j         j        d                                       d          }|                                 t          j         j        d                   }|                                 |                    d                              d           t          dg          t           j	                  } fd}|
                    |           |S )z}
        L{UserDirectory} renders a list of links to available user content
        in response to a I{GET} request.
        r  r  r'  r    r   c                 R   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 )	Nr    liahrefzalice/zAlice (file)zbob.twistd/zBob (twistd))	r   r   r   getElementsByTagNamerY   
firstChildtagNamegetAttributer   )r   documentr  r  rV   r(   s       r!   r   z2UserDirectoryTests.test_render.<locals>.cbRendered  s    "388GO#<#<==H $88>>LUCU-5s;;;U-::6BBHMMMU-8=~NNNS^3S999S^88@@-PPPS^6;^LLLLLr    )r   r  r  rf   r   r  
setContentr   r   r  rW   )r(   r  r)  r   r   rV   s   `    @r!   test_renderzUserDirectoryTests.test_render  s    
 '
277==mLL-- 			"##..s333t$$11
	M 
	M 
	M 
	M 
	M 
	M 	:&&&r    zpwd module requiredc                 l    t          j                    }|                     |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
  assertIdentical_pwdpwd)r(   r  s     r!   test_passwordDatabasez(UserDirectoryTests.test_passwordDatabase  s0     )++	Y^S11111r    )r   r   r   r*   r  r  bytesr  r  r  r%  r*  r0  r<  r   r@  rA  r   r    r!   r  r  |  s         
> > >J J J	45 	4T 	4 	4 	4 	4& & && & &8 8 89 9 9T T T  @ VG*++2 2 ,+2 2 2r    r  )1r*   os.pathr   xml.dom.minidomr   r@  r?  ImportErrorunittestr   zope.interface.verifyr   twisted.internetr   r   twisted.loggerr	   twisted.pythonr
   r   twisted.spreadr   twisted.spread.bananar   twisted.testr   twisted.trial.unittestr   twisted.webr   r   r   r   r   twisted.web.http_headersr   twisted.web.test._utilr   twisted.web.test.requesthelperr   r   rN   r   r#   	Exceptionr,   r.   r   r  r   r    r!   <module>rT     s          ' ' ' ' ' ' CC    
CCC
       . . . . . . + + + + + + + + - - - - - - , , , , , , , ,       , , , , , , & & & & & & + + + + + + A A A A A A A A A A A A A A , , , , , , * * * * * * E E E E E E E E	 	 	 	 	V[ 	 	 	    b(        Y   n8 n8 n8 n8 n88 n8 n8 n8b	       z2 z2 z2 z2 z2 z2 z2 z2 z2 z2s    !!