
    Yf2                        d Z ddlZddlZddlZ	 ddlZn# e$ r dZY nw xY w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mZmZmZmZmZ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"  ee	j#        $                    e
           d           G d de"                      Z% ee	j#        $                    e
           d           G d de"                      Z&dS )z
Whitebox tests for TCP APIs.
    N)skipIf)
interfacesreactor)gatherResultsmaybeDeferred)ProtocolServerFactory)_ACCEPT_ERRORSEAGAINECONNABORTEDEINPROGRESSEMFILEENFILEENOBUFSENOMEMEPERMEWOULDBLOCKPort)log)platform)TestCasez?This test only applies to reactors that implement IReactorFDsetc                   t    e Zd ZdZdZd Zd Zd Z e e	j
                    dk    d          d             Zd	S )
PlatformAssumptionsTestsz4
    Test assumptions about platform behaviors.
    i    c                    g | _         t          {ddlm} t	           |                      dz   }t          j        t          j                  | _        t          j        t          j        || j        d         f           |dz   | _	        d S d S )Nr   )_listOpenFDs      d   )
openSocketsresourcetwisted.internet.processr   len	getrlimitRLIMIT_NOFILEoriginalFileLimit	setrlimitsocketLimit)selfr   newLimits      Q/var/www/html/env/lib/python3.11/site-packages/twisted/test/test_tcp_internals.pysetUpzPlatformAssumptionsTests.setUp4   s     >=====<<>>**Q.H%-%78N%O%OD"&43I!3L(M    (#~D      c                 J   | j         r2| j                                                                          | j         2t          bt          j        t          j                  d         }t          | j        d         |          }t          j        t          j        ||f           d S d S )Nr   r   )	r   popcloser    r#   r$   minr%   r&   )r(   currentHardLimitnewSoftLimits      r*   tearDownz!PlatformAssumptionsTests.tearDownF   s     	+  ""((***  	+
  (1(2HII!Lt5a8:JKKLx5FV7WXXXXX  r,   c                 `    t          j                     }| j                            |           |S )z|
        Create and return a new socket object, also tracking it so it can be
        closed in the test tear down.
        )socketr   append)r(   ss     r*   r5   zPlatformAssumptionsTests.socketR   s+    
 MOO"""r,   win32zhWindows requires an unacceptably large amount of resources to provoke this behavior in the naive manner.c                    |                                  }|                    d           |                                d         }|                    d           |                                  }|                    d           t          | j                  D ]K}	 |                                   # t          $ r'}|j        d         t          t          fv rY d}~ n d}~ww xY w|                     d           |                     |                    d|f          dt          f           |                     t           j        |j                  }|                     |j        d         t          t          f           dS )	z
        Test that the platform accept(2) call fails with either L{EMFILE} or
        L{ENOBUFS} when there are too many file descriptors open.
        )	127.0.0.1r   r      Fr   Nz7Could provoke neither EMFILE nor ENOBUFS from platform.r:   )r5   bindgetsocknamelistensetblockingranger'   OSErrorargsr   r   failassertIn
connect_exr   assertRaiseserroraccept)r(   portserverPortNumberclientieexcs          r*   test_acceptOutOfFilesz.PlatformAssumptionsTests.test_acceptOutOfFiles[   sq    {{}}		"###++--a0A 5!!! t'(( 	Q 	QA   6!9 111EEEEE  IIOPPP 	{,<=>>K@P	
 	
 	

 dk::chqkFG#455555s   B..
C8CCCN)__name__
__module____qualname____doc__r'   r+   r3   r5   r   r   getTyperO    r,   r*   r   r   )   s        
  K. . .$
Y 
Y 
Y   Vg%	5 
%6 %6 
%6 %6 %6r,   r   c                      e Zd ZdZd Zd Zd Zd Zd Zd Z	d Z
 e ej                    d	k    d
          d             Z e ej                    d	k    d          d             Z eej                            d          dk    d          d             Z e ej                    d	k    d          d             Zd ZdS )SelectReactorTestsz7
    Tests for select-specific failure conditions.
    c                 ^    g | _         g | _        t          j        | j        j                   d S N)portsmessagesr   addObserverr6   r(   s    r*   r+   zSelectReactorTests.setUp   s+    
,-----r,   c                 z    t          j        | j        j                   t	          d | j        D                       S )Nc                 6    g | ]}t          |j                  S rU   )r   stopListening).0ps     r*   
<listcomp>z/SelectReactorTests.tearDown.<locals>.<listcomp>   s"    QQQmAO<<QQQr,   )r   removeObserverr[   r6   r   rZ   r]   s    r*   r3   zSelectReactorTests.tearDown   s7    4=/000QQdjQQQRRRr,   c                     t          |||          }|                                 | j                            |           |S )z
        Create, start, and return a new L{Port}, also tracking it so it can
        be stopped in the test tear down.
        	interface)r   startListeningrZ   r6   )r(   
portNumberfactoryrg   rb   s        r*   rI   zSelectReactorTests.port   sE    
 W	:::	
!r,   c                     G fdd          }t                      }|                     d|d          }|                     |d |                       |                                 dt          j                 fd| j        D             }|                     t          |          dd	| j                   d
S )a  
        Test behavior in the face of an exception from C{accept(2)}.

        On any exception which indicates the platform is unable or unwilling
        to allocate further resources to us, the existing port should remain
        listening, a message should be logged, and the exception should not
        propagate outward from doRead.

        @param socketErrorNumber: The errno to simulate from accept.
        c                       e Zd ZdZ fdZdS )9SelectReactorTests._acceptFailureTest.<locals>.FakeSocketzI
            Pretend to be a socket in an overloaded system.
            c                 H    t          t          j                            rY   )rA   osstrerror)r(   socketErrorNumbers    r*   rH   z@SelectReactorTests._acceptFailureTest.<locals>.FakeSocket.accept   s    /=N1O1OPPPr,   NrP   rQ   rR   rS   rH   )rq   s   r*   
FakeSocketrm      s?         Q Q Q Q Q Q Qr,   rs   r   r:   rf   r5   z/Could not accept new connection ({acceptError})c                 t    g | ]4}|                     d           k    o|                     d          k    5S )
log_formatacceptError)get)ra   msgexpectedErrorCodeexpectedFormats     r*   rc   z9SelectReactorTests._acceptFailureTest.<locals>.<listcomp>   sW     
 
 

  %%7 @GGM**.??
 
 
r,   z)Log event for failed accept not found in N)	r	   rI   patchdoReaderrno	errorcoder[   assertGreaterr"   )r(   rq   rs   rj   rI   matchingMessagesry   rz   s    `    @@r*   _acceptFailureTestz%SelectReactorTests._acceptFailureTest   s   	Q 	Q 	Q 	Q 	Q 	Q 	Q 	Q 	Q 	Q  //yyG{y;;

4::<<000J!O,=>
 
 
 
 

 }
 
 
 	 !!A@DO	
 	
 	
 	
 	
r,   c                 6    |                      t                    S )a*  
        C{accept(2)} can fail with C{EMFILE} when there are too many open file
        descriptors in the process.  Test that this doesn't negatively impact
        any other existing connections.

        C{EMFILE} mainly occurs on Linux when the open file rlimit is
        encountered.
        )r   r   r]   s    r*   test_tooManyFilesFromAcceptz.SelectReactorTests.test_tooManyFilesFromAccept        &&v...r,   c                 6    |                      t                    S )z
        Similar to L{test_tooManyFilesFromAccept}, but test the case where
        C{accept(2)} fails with C{ENOBUFS}.

        This mainly occurs on Windows and FreeBSD, but may be possible on
        Linux and other platforms as well.
        )r   r   r]   s    r*   test_noBufferSpaceFromAcceptz/SelectReactorTests.test_noBufferSpaceFromAccept   s     &&w///r,   c                 6    |                      t                    S )z
        Similar to L{test_tooManyFilesFromAccept}, but test the case where
        C{accept(2)} fails with C{ECONNABORTED}.

        It is not clear whether this is actually possible for TCP
        connections on modern versions of Linux.
        )r   r   r]   s    r*    test_connectionAbortedFromAcceptz3SelectReactorTests.test_connectionAbortedFromAccept   s     &&|444r,   r8   z(Windows accept(2) cannot generate ENFILEc                 6    |                      t                    S )z
        Similar to L{test_tooManyFilesFromAccept}, but test the case where
        C{accept(2)} fails with C{ENFILE}.

        This can occur on Linux when the system has exhausted (!) its supply
        of inodes.
        )r   r   r]   s    r*   test_noFilesFromAcceptz)SelectReactorTests.test_noFilesFromAccept   r   r,   z(Windows accept(2) cannot generate ENOMEMc                 6    |                      t                    S )a  
        Similar to L{test_tooManyFilesFromAccept}, but test the case where
        C{accept(2)} fails with C{ENOMEM}.

        On Linux at least, this can sensibly occur, even in a Python program
        (which eats memory like no ones business), when memory has become
        fragmented or low memory has been filled (d_alloc calls
        kmem_cache_alloc calls kmalloc - kmalloc only allocates out of low
        memory).
        )r   r   r]   s    r*   test_noMemoryFromAcceptz*SelectReactorTests.test_noMemoryFromAccept   s     &&v...r,   INFRASTRUCTUREAZUREPIPELINESz(Hangs on Azure Pipelines due to firewallc                    t                      }t          |_        |                     d|d          |                     j                   g fd}|                     |           fd}                     |                       d_                                         | 	                    j        d                                |                                                        | 
                    j        d                                            | 
                    j        d           dS )z
        L{tcp.Port.doRead} increases the number of consecutive
        C{accept} calls it performs if all of the previous C{accept}
        calls succeed; otherwise, it reduces the number to the amount
        of successful calls.
        r   r:   rf   c                  :    D ]} |                                   d S rY   )r/   )rK   clientss    r*   closeAllz7SelectReactorTests.test_acceptScaling.<locals>.closeAll  s+    !   r,   c                      t          j         t           j        t           j                  } |                     d                                j        f           | S )Nr:   )r5   AF_INETSOCK_STREAMconnectgetHostrI   )rK   rI   s    r*   r   z6SelectReactorTests.test_acceptScaling.<locals>.connect  s@    ]6>63EFFFNNK)<=>>>Mr,   r   N)r	   r   protocolrI   
addCleanupr`   r6   numberAcceptsr|   r   assertEqual)r(   rj   r   r   r   rI   s       @@r*   test_acceptScalingz%SelectReactorTests.test_acceptScaling  sD     //#yyG{y;;*+++	 	 	 	 	 	!!!	 	 	 	 	
 	wwyy!!!4-q111wwyy!!! 	+Q/// 	+Q/////r,   z'Windows accept(2) cannot generate EPERMc                     ddg G  fdd          }t                    D ]/}                     t          j         |            j                   0                      j         |            j                   dgt                      }                     d|d          }d|_         	                    |d |                       |
                                                      |j        d           d	S )
z
        C{accept(2)} returning C{EPERM} is treated as a transient
        failure and the call retried no more than the maximum number
        of consecutive C{accept(2)} calls.
        {   r   c                   "    e Zd ZdZ fdZdS )LSelectReactorTests.test_permissionFailure.<locals>.FakeSocketWithAcceptLimit
            Pretend to be a socket in an overloaded system whose
            C{accept} method can only be called
            C{maximumNumberOfAccepts} times.
            c                     dxx         dz  cc<   d         k    r                     d           t          t          t          j        t                              )Nr   r   z(Maximum number of accept calls exceeded.)rC   rA   r   ro   rp   )oselfacceptCallsmaximumNumberOfAcceptsr(   s    r*   rH   zSSelectReactorTests.test_permissionFailure.<locals>.FakeSocketWithAcceptLimit.acceptC  sV    A!#q>$:::IIHIIIeR[%7%7888r,   Nrr   )r   r   r(   s   r*   FakeSocketWithAcceptLimitr   <  sB         9 9 9 9 9 9 9 9 9r,   r   r:   rf   r5   r   N)r@   rF   r5   rG   rH   failureExceptionr	   rI   r   r{   r|   assertEquals)r(   r   _rj   rI   r   r   s   `    @@r*   test_permissionFailurez)SelectReactorTests.test_permissionFailure2  s9    "%c	9 	9 	9 	9 	9 	9 	9 	9 	9 	9 	9 	9 -.. 	P 	PAfl,E,E,G,G,NOOOO$/1J1J1L1L1STTTc//yyG{y;; 

4#<#<#>#>??? 	 	$,a00000r,   c                 b   t          t                    }|                    t          t          t
          g           t          d |D                       dz    G fdd          }t                      }|                     d|d          }| 	                    |d |                       |
                                 |                     t          j                  }|                     dt          |                     |                     |d         j        j        d                    d	S )
z}
        A C{socket.error} raised by C{accept(2)} whose C{errno} is
        unknown to the recovery logic is logged.
        c              3   D   K   | ]}t          |t                    |V  d S rY   )
isinstanceint)ra   rG   s     r*   	<genexpr>zBSelectReactorTests.test_unknownSocketErrorRaise.<locals>.<genexpr>g  s1      II%*UC2H2HIIIIIIIr,   r   c                       e Zd ZdZ fdZdS )YSelectReactorTests.test_unknownSocketErrorRaise.<locals>.FakeSocketWithUnknownAcceptErrorr   c                 $    t          d          )Nzunknown socket error message)rA   )r   unknownAcceptErrors    r*   rH   z`SelectReactorTests.test_unknownSocketErrorRaise.<locals>.FakeSocketWithUnknownAcceptError.acceptq  s    02PQQQr,   Nrr   )r   s   r*    FakeSocketWithUnknownAcceptErrorr   j  s?         R R R R R R Rr,   r   r   r:   rf   r5   N)listr
   extendr   r   r   maxr	   rI   r{   r|   flushLoggedErrorsr5   rG   r   r"   valuerB   )r(   knownErrorsr   rj   rI   failuresr   s         @r*   test_unknownSocketErrorRaisez/SelectReactorTests.test_unknownSocketErrorRaise^  s;   
 >**FE;7888 II;IIIIIAM 		R 	R 	R 	R 	R 	R 	R 	R 	R 	R  //yyG{y;;

4#C#C#E#EFFF))&,77CMM***!*/24FGGGGGr,   N)rP   rQ   rR   rS   r+   r3   rI   r   r   r   r   r   r   rT   r   r   ro   environrw   r   r   r   rU   r,   r*   rW   rW      s       
 . . .
S S S  '
 '
 '
R	/ 	/ 	/0 0 05 5 5 VH')+UVV/ / WV/ VH')+UVV/ / WV/ V

'((,<<2 '0 '0	 '0R VH')+TUU)1 )1 VU)1VH H H H Hr,   rW   )'rS   r}   ro   r5   r    ImportErrorunittestr   twisted.internetr   r   twisted.internet.deferr   r   twisted.internet.protocolr   r	   twisted.internet.tcpr
   r   r   r   r   r   r   r   r   r   r   twisted.pythonr   twisted.python.runtimer   twisted.trial.unittestr   IReactorFDSet
providedByr   rW   rU   r,   r*   <module>r      s[   
  				 OOOO   HHH       0 0 0 0 0 0 0 0 ? ? ? ? ? ? ? ? = = = = = = = =                                + + + + + + + + + + + +  ++G444E X6 X6 X6 X6 X6x X6 X6	 X6v  ++G444E pH pH pH pH pH pH pH	 pH pH pHs    