Ë
    ojì2  ã                   óœ  — d Z ddlZddlZddlZ	 ddl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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	jF                  jI                  e
«       d«       G d„ de"«      «       Z% ee	jF                  jI                  e
«       d«       G d„ de"«      «       Z&y# e$ r dZY Œ¶w xY w)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                   óh   — e Zd ZdZdZd„ Zd„ Zd„ Z e e	j                  «       dk(  d«      d„ «       Zy	)
Ú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   | _	        y y )Nr   )Ú_listOpenFDsé   é   éd   )
ÚopenSocketsÚresourceÚtwisted.internet.processr   ÚlenÚ	getrlimitÚRLIMIT_NOFILEÚoriginalFileLimitÚ	setrlimitÚsocketLimit)Úselfr   ÚnewLimits      úA/usr/lib/python3/dist-packages/twisted/test/test_tcp_internals.pyÚsetUpzPlatformAssumptionsTests.setUp4   s{   € ØˆÔÜÐõ >ä™<›>Ó*¨QÑ.ˆHÜ%-×%7Ñ%7¼×8NÑ8NÓ%OˆDÔ"Ü×ÑÜ×&Ñ&¨°4×3IÑ3IÈ!Ñ3LÐ(Môð  (¨#™~ˆDÕð  ó    c                 ó^  — | j                   r5| j                   j                  «       j                  «        | j                   rŒ5t        �ft        j                  t        j
                  «      d   }t        | j                  d   |«      }t        j                  t        j
                  ||f«       y y )Nr   r   )	r   ÚpopÚcloser    r#   r$   Úminr%   r&   )r(   ÚcurrentHardLimitÚnewSoftLimits      r*   ÚtearDownz!PlatformAssumptionsTests.tearDownF   sŽ   € Ø×ÒØ×Ñ× Ñ Ó"×(Ñ(Ô*ð ×ÓäÐô
  (×1Ñ1´(×2HÑ2HÓIÈ!ÑLÐÜ˜t×5Ñ5°aÑ8Ð:JÓKˆLÜ×Ñœx×5Ñ5¸ÐFVÐ7WÕXð  r,   c                 ód   — t        j                   «       }| 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(   € ô
 �M‰M‹OˆØ×Ñ×Ñ Ô"Øˆr,   Úwin32zhWindows requires an unacceptably large amount of resources to provoke this behavior in the naive manner.c                 ó¦  — | j                  «       }|j                  d«       |j                  «       d   }|j                  d«       | j                  «       }|j	                  d«       t        | j                  «      D ]  }	 | j                  «        Œ | j                  d«       | j                  |j                  d|f«      dt        f«       | j                  t         j                   |j"                  «      }| j                  |j                  d   t        t        f«       y# t        $ r'}|j                  d   t        t        fv rY d}~ Œ§‚ d}~ww xY w)	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[   s   € ð �{‰{‹}ˆØ�	‰	Ð"Ô#Ø×+Ñ+Ó-¨aÑ0ÐØ�‰�AŒð —‘“ˆØ×Ñ˜5Ô!ô �t×'Ñ'Ó(ò 	QˆAðØ—‘•ð	Qð �I‰IÐOÔPð 	�‰Ø×Ñ˜{Ð,<Ð=Ó>ÀÄKÐ@Pô	
ð
 ×Ñ¤§¡¨d¯k©kÓ:ˆØ�‰�c—h‘h˜q‘k¤F¬GÐ#4Õ5øô% ò Ø—6‘6˜!‘9¤¬Ð 1Ñ1åð ûðús   Â D Ä 	EÄ)EÅ
EÅEN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r'   r+   r3   r5   r   r   ÚgetTyperO   © r,   r*   r   r   )   sO   „ ñ
ð €Kò.ò$
Yòñ Øˆ×ÑÓ˜gÑ%ð	5óñ
%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"                  j%                  d«      dk(  d«      d„ «       Z e ej                  «       d	k(  d«      d„ «       Zd„ Zy)ÚSelectReactorTestsz7
    Tests for select-specific failure conditions.
    c                 ór   — g | _         g | _        t        j                  | j                  j                  «       y ©N)ÚportsÚmessagesr   ÚaddObserverr6   ©r(   s    r*   r+   zSelectReactorTests.setUp‘   s&   € ØˆŒ
ØˆŒÜ�‰˜Ÿ™×,Ñ,Õ-r,   c                 óÊ   — t        j                  | j                  j                  «       t	        | j
                  D �cg c]  }t        |j                  «      ‘Œ c}«      S c c}w rY   )r   ÚremoveObserverr[   r6   r   rZ   r   ÚstopListening)r(   Úps     r*   r3   zSelectReactorTests.tearDown–   s@   € Ü×Ñ˜4Ÿ=™=×/Ñ/Ô0ÜÀdÇjÁjÖQÀœm¨A¯O©OÕ<ÒQÓRÐRùÒQs   ½A c                 óx   — t        |||¬«      }|j                  «        | j                  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Úfactoryrd   ra   s        r*   rI   zSelectReactorTests.portš   s5   € ô
 �˜W°	Ô:ˆØ	×ÑÔØ�
‰
×Ñ˜!ÔØˆr,   c                 ó²  ‡—  G ˆfd„d«      }t        «       }| j                  d|d¬«      }| j                  |d |«       «       |j                  «        d}t        j
                  ‰   }| j                  D �cg c],  }|j                  d«      |k(  xr |j                  d	«      |k(  ‘Œ. }}| j                  t        |«      dd
| j                  ›�«       yc c}w )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y)ú9SelectReactorTests._acceptFailureTest.<locals>.FakeSocketzI
            Pretend to be a socket in an overloaded system.
            c                 óB   •— t        ‰t        j                  ‰«      «      ‚rY   )rA   ÚosÚstrerror)r(   ÚsocketErrorNumbers    €r*   rH   z@SelectReactorTests._acceptFailureTest.<locals>.FakeSocket.acceptµ   s   ø€ ÜÐ/´·±Ð=NÓ1OÓPÐPr,   N©rP   rQ   rR   rS   rH   )rn   s   €r*   Ú
FakeSocketrj   °   s   ø„ ñõQr,   rp   r   r:   rc   r5   z/Could not accept new connection ({acceptError})Ú
log_formatÚacceptErrorz)Log event for failed accept not found in N)
r	   rI   ÚpatchÚdoReadÚerrnoÚ	errorcoder[   ÚgetÚassertGreaterr"   )	r(   rn   rp   rg   rI   ÚexpectedFormatÚexpectedErrorCodeÚmsgÚmatchingMessagess	    `       r*   Ú_acceptFailureTestz%SelectReactorTests._acceptFailureTest¤   sÙ   ø€ ÷	Qó 	Qô  “/ˆØ�y‰y˜˜G¨{ˆyÓ;ˆØ�
‰
�4˜¡:£<Ô0à�‰ŒàJˆÜ!ŸO™OÐ,=Ñ>Ðð —}‘}ö
ð
 ð —‘˜Ó%¨Ñ7ò @Ø—G‘G˜MÓ*Ð.?Ñ?ñ@ð
Ðð 
ð 	×ÑÜÐ Ó!ÙØ@DÇÂÐOõ	
ùò
s   Á71Cc                 ó,   — | j                  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                 ó,   — | j                  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                 ó,   — | j                  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Ð4r,   r8   z(Windows accept(2) cannot generate ENFILEc                 ó,   — | j                  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                 ó,   — | j                  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                 ó8  ‡‡— t        «       }t        |_        | j                  d|d¬«      Š| j	                  ‰j
                  «       g Šˆfd„}| j	                  |«       ˆfd„}‰j                   |«       «       d‰_        ‰j                  «        | j                  ‰j                  d«       ‰j                   |«       «       ‰j                  «        | j                  ‰j                  d«       ‰j                  «        | j                  ‰j                  d«       y)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:   rc   c                  ó4   •— ‰D ]  } | j                  «        Œ y rY   )r/   )rK   Úclientss    €r*   ÚcloseAllz7SelectReactorTests.test_acceptScaling.<locals>.closeAll  s   ø€ Ø!ò �Ø—‘•ñr,   c                  óÂ   •— t        j                   t         j                  t         j                  «      } | j                  d‰j	                  «       j
                  f«       | S )Nr:   )r5   ÚAF_INETÚSOCK_STREAMÚconnectÚgetHostrI   )rK   rI   s    €r*   r’   z6SelectReactorTests.test_acceptScaling.<locals>.connect  s?   ø€ Ü—]‘]¤6§>¡>´6×3EÑ3EÓFˆFØ�N‰N˜K¨¯©«×)<Ñ)<Ð=Ô>ØˆMr,   r   N)r	   r   ÚprotocolrI   Ú
addCleanupr`   r6   ÚnumberAcceptsrt   rx   ÚassertEqual)r(   rg   rŽ   r’   r�   rI   s       @@r*   Útest_acceptScalingz%SelectReactorTests.test_acceptScaling  sÞ   ù€ ô  “/ˆÜ#ˆÔØ�y‰y˜˜G¨{ˆyÓ;ˆØ�‰˜×*Ñ*Ô+àˆô	ð 	�‰˜Ô!ô	ð
 	�‰‘w“yÔ!ØˆÔØ�‰ŒØ×Ñ˜4×-Ñ-¨qÔ1à�‰‘w“yÔ!Ø�‰Œð 	×Ñ˜×+Ñ+¨QÔ/à�‰Œð 	×Ñ˜×+Ñ+¨QÕ/r,   z'Windows accept(2) cannot generate EPERMc                 óÜ  ‡ ‡‡— dŠdgŠ G ˆˆˆ fd„d«      }t        ‰«      D ]1  }‰ j                  t        j                   |«       j                  «       Œ3 ‰ j                  ‰ j
                   |«       j                  «       dgŠt        «       }‰ j                  d|d¬«      }d|_        ‰ j                  |d |«       «       |j                  «        ‰ j                  |j                  d«       y	)
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y)ú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   ‰kD  r‰j                  d«       t        t        t        j                  t        «      «      ‚)Nr   r   z(Maximum number of accept calls exceeded.)rC   rA   r   rl   rm   )ÚoselfÚacceptCallsÚmaximumNumberOfAcceptsr(   s    €€€r*   rH   zSSelectReactorTests.test_permissionFailure.<locals>.FakeSocketWithAcceptLimit.acceptC  sA   ø€ Ø˜A“ !Ñ#“Ø˜q‘>Ð$:Ò:Ø—I‘IÐHÔIÜœe¤R§[¡[´Ó%7Ó8Ð8r,   Nro   )r    r¡   r(   s   €€€r*   ÚFakeSocketWithAcceptLimitrœ   <  s   ø„ ñ÷9r,   r¢   r:   rc   r5   r   N)r@   rF   r5   rG   rH   ÚfailureExceptionr	   rI   r–   rs   rt   ÚassertEquals)r(   r¢   Ú_rg   rI   r    r¡   s   `    @@r*   Útest_permissionFailurez)SelectReactorTests.test_permissionFailure2  sÖ   ú€ ð "%ÐØ�cˆ÷	9õ 	9ô Ð-Ó.ò 	PˆAØ×ÑœfŸl™lÑ,EÓ,G×,NÑ,NÕOð	Pð 	×Ñ˜$×/Ñ/Ñ1JÓ1L×1SÑ1SÔTà�cˆä“/ˆØ�y‰y˜˜G¨{ˆyÓ;ˆØ ˆÔØ�
‰
�4˜Ñ#<Ó#>Ô?ð 	�‰Œð 	×Ñ˜$×,Ñ,¨aÕ0r,   c                 óþ  ‡— t        t        «      }|j                  t        t        t
        g«       t        d„ |D «       «      dz   Š G ˆfd„d«      }t        «       }| j                  d|d¬«      }| j                  |d |«       «       |j                  «        | j                  t        j                  «      }| j                  dt        |«      «       | j                  |d   j                   j"                  d   ‰«       y	)
z}
        A C{socket.error} raised by C{accept(2)} whose C{errno} is
        unknown to the recovery logic is logged.
        c              3   óB   K  — | ]  }t        |t        «      sŒ|–— Œ y ­wrY   )Ú
isinstanceÚint)Ú.0rG   s     r*   ú	<genexpr>zBSelectReactorTests.test_unknownSocketErrorRaise.<locals>.<genexpr>g  s   è ø€ ÒI˜%´*¸UÄCÕ2H”ÑIùs   ‚˜r   c                   ó   •— e Zd ZdZˆ fd„Zy)ú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   ø€ ÜÐ0Ð2PÓQÐQr,   Nro   )r°   s   €r*   Ú FakeSocketWithUnknownAcceptErrorr®   j  s   ø„ ñõRr,   r±   r   r:   rc   r5   N)Úlistr
   Úextendr   r   r   Úmaxr	   rI   rs   rt   ÚflushLoggedErrorsr5   rG   r—   r"   ÚvaluerB   )r(   ÚknownErrorsr±   rg   rI   Úfailuresr°   s         @r*   Útest_unknownSocketErrorRaisez/SelectReactorTests.test_unknownSocketErrorRaise^  sÒ   ø€ ô
 œ>Ó*ˆØ×ÑœF¤E¬;Ð7Ô8ô ÑI ;ÔIÓIÈAÑMð 	÷	Ró 	Rô  “/ˆØ�y‰y˜˜G¨{ˆyÓ;ˆØ�
‰
�4˜Ñ#CÓ#EÔFà�‰Œà×)Ñ)¬&¯,©,Ó7ˆØ×Ñ˜œC ›MÔ*Ø×Ñ˜ !™×*Ñ*×/Ñ/°Ñ2Ð4FÕGr,   N)rP   rQ   rR   rS   r+   r3   rI   r}   r   r‚   r„   r   r   rT   r†   rˆ   rl   Úenvironrw   r˜   r¦   r¹   rU   r,   r*   rW   rW   ˆ   sñ   „ ñ
ò.ò
Sòò'
òR	/ò0ò5ñ ÐˆH×ÑÓ 'Ñ)Ð+UÓVñ/ó Wð/ñ ÐˆH×ÑÓ 'Ñ)Ð+UÓVñ/ó Wð/ñ Ø
�
‰
�‰Ð'Ó(Ð,<Ñ<Ø2óñ'0ó	ð'0ñR ÐˆH×ÑÓ 'Ñ)Ð+TÓUñ)1ó Vð)1óVHr,   rW   )'rS   ru   rl   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ß   ðñó
 Û 	Û ðÛõ ç 0ß ?ß =÷÷ ÷ ñ õ Ý +Ý +ñ Ø× Ñ ×+Ñ+¨GÓ4Ð4ØEóôX6˜xó X6ó	ðX6ñv Ø× Ñ ×+Ñ+¨GÓ4Ð4ØEóôpH˜ó pHó	ñpHøð{ ò Ø‚Hðús   �C ÃCÃ
C