ó
[³XMc           @   sÃ   d  Z  e Z d d l 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 e
 d	 k r d d
 l m Z n d Z d d d „  ƒ  YZ d g Z d S(   s/   
Tests for implementations of L{IReactorTime}.
iÿÿÿÿN(   t   TimeoutError(   t   TestCaset   SkipTest(   t   platformType(   t   namedAny(   t   log(   t   Failuret   posix(   t   processt   ReactorBuilderc        	   B   sŒ   e  Z d  Z d d d d d d d d d	 g	 Z d Z d Z d Z i  Z d
 „  Z	 d „  Z
 d „  Z d „  Z d d „ Z d „  Z e e ƒ Z RS(   s¬  
    L{TestCase} mixin which provides a reactor-creation API.  This mixin
    defines C{setUp} and C{tearDown}, so mix it in before L{TestCase} or call
    its methods from the overridden ones in the subclass.

    @cvar skippedReactors: A dict mapping FQPN strings of reactors for
        which the tests defined by this class will be skipped to strings
        giving the skip message.
    @cvar requiredInterfaces: A C{list} of interfaces which the reactor must
        provide or these tests will be skipped.  The default, C{None}, means
        that no interfaces are required.
    @ivar reactorFactory: A no-argument callable which returns the reactor to
        use for testing.
    @ivar originalHandler: The SIGCHLD handler which was installed when setUp
        ran and which will be re-installed when tearDown runs.
    @ivar _reactors: A list of FQPN strings giving the reactors for which
        TestCases will be created.
    s,   twisted.internet.selectreactor.SelectReactors(   twisted.internet.pollreactor.PollReactors*   twisted.internet.epollreactor.EPollReactors*   twisted.internet.glib2reactor.Glib2Reactors(   twisted.internet.gtk2reactor.Gtk2Reactors(   twisted.internet.kqreactor.KQueueReactors/   twisted.internet.win32eventreactor.Win32Reactors0   twisted.internet.iocpreactor.reactor.IOCPReactors$   twisted.internet.cfreactor.CFReactorc         C   s.   t  d k r* t j t j t j ƒ |  _ n  d S(   s›   
        Clear the SIGCHLD handler, if there is one, to ensure an environment
        like the one which exists prior to a call to L{reactor.run}.
        R   N(   R   t   signalt   SIGCHLDt   SIG_DFLt   originalHandler(   t   self(    (    sG   /usr/lib/python2.7/dist-packages/twisted/internet/test/reactormixins.pyt   setUp=   s    c         C   sl   |  j  d k	 r( t j t j |  j  ƒ n  t d k	 rh x1 t j rd t j d t j f ƒ t j ƒ  q7 Wn  d S(   s|   
        Restore the original SIGCHLD handler and reap processes as long as
        there seem to be any remaining.
        s1   ReactorBuilder.tearDown reaping some processes %rN(	   R   t   NoneR
   R   R   t   reapProcessHandlersR   t   msgt   reapAllProcesses(   R   (    (    sG   /usr/lib/python2.7/dist-packages/twisted/internet/test/reactormixins.pyt   tearDownF   s    c         C   s•   | j  ƒ  t | d d ƒ d k	 r` x+ | j D]  } | j | ƒ | j d ƒ q, W| j j ƒ  n  | j ƒ  | j ƒ  } x | D] } | j	 ƒ  q} Wd S(   s   
        Clean up any resources which may have been allocated for the given
        reactor by its creation or by a test which used it.
        t   _internalReadersN(
   t   _uninstallHandlert   getattrR   R   t   removeReadert   connectionLostt   cleart   disconnectAllt   getDelayedCallst   cancel(   R   t   reactort   readert   callst   c(    (    sG   /usr/lib/python2.7/dist-packages/twisted/internet/test/reactormixins.pyt   unbuildReactorU   s    

c      	      s@  y$ d d l  m } d d l m } Wn t k
 r7 n. Xt | | ƒ re |  j | k re t d ƒ ‚ n  y |  j ƒ  ‰  Wn6 t j	 d	 d ƒ |  j ƒ  t t ƒ  j ƒ  ƒ ‚ n| X|  j d	 k	 r)t ‡  f d †  |  j ƒ } | r)|  j ˆ  ƒ t d ˆ  d j g  | D] } t | ƒ ^ qƒ f ƒ ‚ q)n  |  j |  j ˆ  ƒ ˆ  S(
   sK   
        Create and return a reactor using C{self.reactorFactory}.
        iÿÿÿÿ(   t	   CFReactor(   R   su   CFReactor uses APIs which manipulate global state, so it's not safe to run its own reactor-builder tests under itselfs   Failed to install reactorc            s   |  j  ˆ  ƒ S(   N(   t
   providedBy(   t   required(   R   (    sG   /usr/lib/python2.7/dist-packages/twisted/internet/test/reactormixins.pyt   <lambda>”   s    s   %r does not provide %st   ,N(   t   twisted.internet.cfreactorR#   t   twisted.internetR   t   ImportErrort
   isinstancet   reactorFactoryR   R   t   errR   t   flushLoggedErrorsR   t   getErrorMessaget   requiredInterfacest   filterR"   t   joint   reprt
   addCleanup(   R   R#   t   globalReactort   missingt   x(    (   R   sG   /usr/lib/python2.7/dist-packages/twisted/internet/test/reactormixins.pyt   buildReactoru   s2    
8c            sm   | d k r |  j ƒ  } n  g  ‰ ‡ ‡  f d †  } ˆ  j | | ƒ ˆ  j ƒ  ˆ ri t d | f ƒ ‚ n  d S(   sº  
        Run the reactor for at most the given amount of time.

        @param reactor: The reactor to run.

        @type timeout: C{int} or C{float}
        @param timeout: The maximum amount of time, specified in seconds, to
            allow the reactor to run.  If the reactor is still running after
            this much time has elapsed, it will be stopped and an exception
            raised.  If C{None}, the default test method timeout imposed by
            Trial will be used.  This depends on the L{IReactorTime}
            implementation of C{reactor} for correct operation.

        @raise TimeoutError: If the reactor is still running after C{timeout}
            seconds.
        c              s   ˆ  j  d  ƒ ˆ j ƒ  d  S(   N(   t   appendR   t   stop(    (   t   timedOutR   (    sG   /usr/lib/python2.7/dist-packages/twisted/internet/test/reactormixins.pyR:   ³   s    s&   reactor still running after %s secondsN(   R   t
   getTimeoutt	   callLatert   runR    (   R   R   t   timeoutR:   (    (   R   R;   sG   /usr/lib/python2.7/dist-packages/twisted/internet/test/reactormixins.pyt
   runReactorž   s    
c            s†   i  } xy ˆ  j  D]n ‰ ˆ j d ƒ d } ˆ  j d | j d d ƒ } d ˆ  t f ‡ ‡  f d †  ƒ  Y} | | _ | | | j <q W| S(   s“   
        Create a L{TestCase} subclass which mixes in C{cls} for each known
        reactor and return a dict mapping their names to them.
        t   .iÿÿÿÿt   _t   testcasec              sY   e  Z ˆ j Z ˆ  ˆ j k r. ˆ j ˆ  Z n  y e ˆ  ƒ Z Wn e ƒ  j ƒ  Z n XRS(    (   t   __name__t
   __module__t   skippedReactorst   skipR   R,   R   R/   (    (   R   t   cls(    sG   /usr/lib/python2.7/dist-packages/twisted/internet/test/reactormixins.pyRC   Ç   s   	(   t	   _reactorst   splitRD   t   replaceR   (   RH   t   classest   shortReactorNamet   nameRC   (    (   RH   R   sG   /usr/lib/python2.7/dist-packages/twisted/internet/test/reactormixins.pyt   makeTestCaseClasses¾   s    "	N(   RD   RE   t   __doc__RI   R   R,   R   R0   RF   R   R   R"   R8   R@   RO   t   classmethod(    (    (    sG   /usr/lib/python2.7/dist-packages/twisted/internet/test/reactormixins.pyR	      s*   					 	) 	(    (   RP   t   typet   __metaclass__R
   t   twisted.internet.deferR    t   twisted.trial.unittestR   R   t   twisted.python.runtimeR   t   twisted.python.reflectR   t   twisted.pythonR   t   twisted.python.failureR   R)   R   R   R	   t   __all__(    (    (    sG   /usr/lib/python2.7/dist-packages/twisted/internet/test/reactormixins.pyt   <module>   s   »