U
    
W[R                     @   s  d dl mZmZmZ d dlZd dlZd dlZd dl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 d dlmZ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 dddddddZ dd Z!dd Z"dd Z#dd Z$dd Z%dd Z&dej'fde&fdZ(dd Z)G d d! d!e*Z+G d"d# d#e+ej,ej-Z,d$d% Z.d&d' Z/d(d) Z0d*d+ Z1G d,d- d-e2Z3d.d/ Z4d0d1 Z5dS )2    )absolute_importdivisionprint_functionN)defer)app)usagereflectfailure)FilePath)namedModule)long)plugin)runneritrialreporterdefaultbriefverbose)plainr   emacsr   cgitbr   c                 C   s   d}|  |t| }| |}|dks0|dkr>td| f | || d}i }|D ]T}t| dkrnqX|d}t|dkrtd| |f |d	  ||d  < qX|S )
a  
    Accepts a single line in Emacs local variable declaration format and
    returns a dict of all the variables {name: value}.
    Raises ValueError if 'line' is in the wrong format.

    See http://www.gnu.org/software/emacs/manual/html_node/File-Variables.html
    z-*-z)%r not a valid local variable declaration;r   :   z"%r contains invalid declaration %r   )findlenrfind
ValueErrorsplitstrip)lineZparenstartenditemsZ	localVarsitemr     r'   7/usr/lib/python3/dist-packages/twisted/scripts/trial.py_parseLocalVariables&   s"    

r)   c              	   C   sX   t | d}| | g}W 5 Q R X |D ](}zt|W   S  tk
rP   Y q*X q*i S )z
    Accepts a filename and attempts to load the Emacs variable declarations
    from that file, simulating what Emacs does.

    See http://www.gnu.org/software/emacs/manual/html_node/File-Variables.html
    r)openreadliner)   r   )filenameflinesr"   r'   r'   r(   loadLocalVariables@   s    r0   c                 C   s&   t | dd }|d krg S |dS )Nztest-case-name,)r0   getr    )r-   ZtestCaseVarr'   r'   r(   getTestModulesQ   s    r3   c                 C   s*   t j| }|do(t j|d dkS )z
    Returns true if 'filename' looks like a file containing unit tests.
    False otherwise.  Doesn't care whether filename exists.
    Ztest_r   z.py)ospathbasename
startswithsplitext)r-   r6   r'   r'   r(   
isTestFileX   s    
r9   c                   C   s   t dd ttjD S )Nc                 S   s   g | ]
}|j qS r'   )longOpt).0pr'   r'   r(   
<listcomp>c   s     z#_reporterAction.<locals>.<listcomp>)r   CompleteListr   
getPluginsr   	IReporterr'   r'   r'   r(   _reporterActionb   s    

rA   c              	   C   sh   t | dd}|dk	rt | |} t | dd}|dk	r8|jS zt| d W S  ttfk
rb   Y dS X dS )aH  
    Try to find the source line of the given test thing.

    @param testThing: the test item to attempt to inspect
    @type testThing: an L{TestCase}, test method, or module, though only the
        former two have a chance to succeed
    @rtype: int
    @return: the starting source line, or -1 if one couldn't be found
    Z_testMethodNameN__code__r   r   )getattrco_firstlinenoinspectZgetsourcelinesIOError	TypeError)Z	testThingmethodcoder'   r'   r(   _maybeFindSourceLineg   s    
rJ   zCalphabetical order for test methods, arbitrary order for test caseszDattempt to run test cases and methods in the order they were defined)ZalphabeticalZtoptobottomc                 C   s,   | t kr(tdddd t D f | S )ai  
    Check that the given order is a known test running order.

    Does nothing else, since looking up the appropriate callable to sort the
    tests should be done when it actually will be used, as the default argument
    will not be coerced by this function.

    @param order: one of the known orders in C{_runOrders}
    @return: the order unmodified
    z9--order must be one of: %s. See --help-orders for detailsz, c                 s   s   | ]}t |V  qd S N)repr)r;   orderr'   r'   r(   	<genexpr>   s     z&_checkKnownRunOrder.<locals>.<genexpr>)
_runOrdersr   
UsageErrorjoin)rM   r'   r'   r(   _checkKnownRunOrder   s    rR   c                
   @   sJ  e Zd ZdZdZddgdddgdd	d
gdd	dgdddgdd	dgdd	dgdddggZddd	degddd	dgdd	ddgd d	d!d"ggZej	e
eeejd#d$ejd%d$d&ejd'd(d)d*gd+ZejZd	Zd,d- Zd.d/ Zd0d1 Zd2d3 Zd4d5 Zd6d7 Zd8d9 Zd:d; Zd<d= Zd>d? Zd@dA ZdBdC ZdDdE Z dFdG Z!dHdI Z"dJdK Z#d	S )L_BasicOptionszC
    Basic options shared between trial and its local workers.
    zutrial loads and executes a suite of unit tests, obtained from modules, packages and files listed on the command line.helph
no-recurseNzDon't recurse into packageszhelp-ordersNz%Help on available test running orderszhelp-reportersz,Help on available output plugins (reporters)rterrorsez;realtime errors, print out tracebacks as soon as they occurunclean-warningsz'Turn dirty reactor errors into warningsforce-gcz<Have Trial run gc.collect() before and after each test case.	exitfirstxzSExit after the first non-successful result (cannot be specified along with --jobs).rM   ozRSpecify what order to run test cases and methods. See --help-orders for more info.randomzz2Run tests in random order using the specified seedtemp-directoryZ_trial_tempz+Path to use as working directory for tests.r   r   zKThe reporter to use for this test run.  See --help-reporters for more info.log file name)descrzrandom seed)rM   r   logfiler_   z*.pyz/file | module | package | TestCase | testMethodT)rc   repeat)
optActionsZextraActionsc                 C   s   g | d< t j|  d S Ntests)r   Options__init__selfr'   r'   r(   rj      s    z_BasicOptions.__init__c                 C   sB   t tjd }|dr8dtjtj	|
dd}d|f S )Nr   z	.__main__z{} -m {} zD%s [options] [[file|package|module|TestCase|testmethod]...]
        )r   ZfilenameToModuleNamesysargvendswithformatr4   r5   r6   
executablereplace)rl   ZexecutableNamer'   r'   r(   getSynopsis   s    

z_BasicOptions.getSynopsisc                 C   s*   d}t | d |}td|jf  |S )zx
        Return a L{FilePath} representing the directory into which coverage
        results should be written.
        coveragera   z!Setting coverage directory to %s.)r
   Zchildprintr5   )rl   coverdirresultr'   r'   r(   rw      s    z_BasicOptions.coverdirc                 C   s2   ddl }|jddd| _t| jj d| d< dS )z
        Generate coverage information in the coverage file in the
        directory specified by the temp-directory option.
        r   Nr   )counttraceTru   )rz   ZTracetracerrn   settraceZglobaltrace)rl   rz   r'   r'   r(   opt_coverage   s    z_BasicOptions.opt_coveragec                 C   s\   t j|s"tjd|f  dS t j|}t|rF| d | n| d 	t
| dS )zG
        Filename to grep for test cases (-*- test-case-name).
        zFile %r doesn't exist
Nrh   )r4   r5   isfilern   stderrwriteabspathr9   appendextendr3   )rl   r-   r'   r'   r(   opt_testmodule   s    z_BasicOptions.opt_testmodulec                 C   s   ddl m} t| dS )z
        Print an insanely verbose log of everything that happens.  Useful
        when debugging freezes or locks in complex code.
        r   )spewerN)Ztwisted.python.utilr   rn   r|   )rl   r   r'   r'   r(   opt_spew  s    z_BasicOptions.opt_spewc                 C   sB   d}t | tt D ]\}\}}t d|d| qtd d S )NzTrial can attempt to run test cases and their methods in a few different orders. You can select any of the following options using --order=<foo>.
   	r   )rv   sortedrO   r%   rn   exit)rl   synopsisnamedescription_r'   r'   r(   opt_help_orders   s
    z_BasicOptions.opt_help_ordersc                 C   s>   d}t | ttjD ]}t d|jd|j qtd d S )NzTrial's output can be customized using plugins called Reporters. You can
select any of the following reporters using --reporter=<foo>
r   r   r   )	rv   r   r?   r   r@   r:   r   rn   r   )rl   r   r<   r'   r'   r(   opt_help_reporters+  s
    z _BasicOptions.opt_help_reportersc                 C   s   d| d< t   dS )z/
        Disable the garbage collector
        T	disablegcN)gcdisablerk   r'   r'   r(   opt_disablegc5  s    z_BasicOptions.opt_disablegcc                 C   s4   zt | | d< W n tk
r.   tdY nX dS )z
        Specify the format to display tracebacks with. Valid formats are
        'plain', 'emacs', and 'cgitb' which uses the nicely verbose stdlib
        cgitb.text function
        tbformatz.tbformat must be 'plain', 'emacs', or 'cgitb'.N)TBFORMAT_MAPKeyErrorr   rP   )rl   Zoptr'   r'   r(   opt_tbformat=  s    z_BasicOptions.opt_tbformatc              	   C   sF   zt t| W n" ttfk
r4   tdY nX t|| d< dS )z-
        see sys.setrecursionlimit()
        z-argument to recursionlimit must be an integerrecursionlimitN)rn   setrecursionlimitintrG   r   r   rP   )rl   argr'   r'   r(   opt_recursionlimitJ  s    
z _BasicOptions.opt_recursionlimitc                 C   sl   zt || d< W n tk
r.   tdY n:X | d dk rHtdn | d dkrht t d | d< d S )Nr_   z/Argument to --random must be a positive integerr   d   )r   r   r   rP   time)rl   optionr'   r'   r(   
opt_randomW  s    
z_BasicOptions.opt_randomc                 C   sD   || d< | dD ],}|tjkr4tjd|f td dtj|< qdS )zP
        Fake the lack of the specified modules, separated with commas.
        without-moduler1   z/Module '%s' already imported, disabling anyway.)categoryN)r    rn   moduleswarningswarnRuntimeWarning)rl   r   moduler'   r'   r(   opt_without_modulee  s    
z _BasicOptions.opt_without_modulec                 G   s   | d  | d S rg   )r   )rl   argsr'   r'   r(   	parseArgsr  s    z_BasicOptions.parseArgsc                 C   sH   t tjD ],}d|j|jf }|j|krt|  S qt	
dd S )Nz%s.%szVOnly pass names of Reporter plugins to --reporter. See --help-reporters for more info.)r   r?   r   r@   r   klassr:   r   namedAnyr   rP   )rl   r   r<   Zqualr'   r'   r(   _loadReporterByNamev  s
    
z!_BasicOptions._loadReporterByNamec                 C   sH   |  | d | d< d| kr"d| d< | d d k	rD| d d k	rDtdd S )Nr   r   r   rM   r_   z-You can't specify --random when using --order)r   r   rP   rk   r'   r'   r(   postOptions  s    z_BasicOptions.postOptions)$__name__
__module____qualname____doc__ZlongdescoptFlagsrR   optParametersr   Completionsr>   rO   rA   ZCompleteFilesZ	CompletercompDatar   TreeReporterfallbackReporterr{   rj   rt   rw   r}   r   r   r   r   r   r   r   r   r   r   r   r   r'   r'   r'   r(   rS      sz   

 

	

rS   c                   @   s   e Zd ZdZdddgdddgdd	d
gdddgdd	dgdddggZdd	ddgddddgddd	dggZejedddge	d d!Z
d"d#d$gZd%d&d'gZejZd	Zd	Zd(d) Zd*d+ Zd,d- Zd	S ).ri   a  
    Options to the trial command line tool.

    @ivar _workerFlags: List of flags which are accepted by trial distributed
        workers. This is used by C{_getWorkerArguments} to build the command
        line arguments.
    @type _workerFlags: C{list}

    @ivar _workerParameters: List of parameter which are accepted by trial
        distributed workers. This is used by C{_getWorkerArguments} to build
        the command line arguments.
    @type _workerParameters: C{list}
    debugbziRun tests in a debugger. If that debugger is pdb, will load '.pdbrc' from current directory if it exists.debug-stacktracesBz2Report Deferred creation and callback stack tracesnopmNzFdon't automatically jump into debugger for postmorteming of exceptionsdry-runnzdo everything but run the testsprofilez#Run tests under the Python profileruntil-failureuzRepeat test until it failsdebuggerpdbzBthe fully qualified name of a debugger to use if --debug is passedrd   lztest.logrb   jobsjzNumber of local workers to runr   r   r   )r   r   )rf   r   r[   ru   r   Zreactorr   c                 C   sN   zt |}W n" tk
r.   td| Y nX |dkrBtd|| d< dS )zN
        Number of local workers to run, a strictly positive integer.
        z,Expecting integer argument to jobs, got '%s'r   z4Argument to jobs must be a strictly positive integerr   N)r   r   r   rP   )rl   Znumberr'   r'   r(   opt_jobs  s    
zOptions.opt_jobsc                 C   sp   g }| j D ]*}| |dk	r
| | r
|d|f  q
| jD ].}| |dk	r<|d|f t| | g q<|S )zJ
        Return a list of options to pass to distributed workers.
        Nz--%s)_workerFlagsr2   r   _workerParametersr   str)rl   r   r   r'   r'   r(   _getWorkerArguments  s    

zOptions._getWorkerArgumentsc                 C   sb   t |  | d r>ddddg}|D ]}| | r"td| q"| d r^| d sXtdd	t_d S )
Nr   r   r   r   r\   z(You can't specify --%s when using --jobsr   z+You must specify --debug when using --nopm F)rS   r   r   rP   r	   ZDO_POST_MORTEM)rl   Z	conflictsr   r'   r'   r(   r     s    

zOptions.postOptions)r   r   r   r   r   r   r   r   r>   rA   r   r   r   r   r   r   Zextrar{   r   r   r   r'   r'   r'   r(   ri     s2   




ri   c                 C   s.   | d rt   | d s | d r*td d S )Nr   r   T)r	   ZstartDebugModer   ZsetDebugging)configr'   r'   r(   _initialDebugSetup  s    r   c                 C   s$   t | }| d  }|j| d |dS )NrV   rh   )recurse)
_getLoaderZloadByNames)r   loaderr   r'   r'   r(   	_getSuite  s    
r   c                    sx   t  }| d rFt   | d   fdd|_td| d   n| d rdt| d  \}}||_| d stt j|_	|S )Nr_   c                    s      S rK   )r_   )r]   Zrandomerr'   r(   <lambda>      z_getLoader.<locals>.<lambda>z$Running tests shuffled with seed %d
rM   r   )
r   Z
TestLoaderr_   ZRandomZseedsorterrv   rO   ZDestructiveTestSuiteZsuiteFactory)r   r   r   r   r'   r   r(   r     s    r   c               
   C   s   t  } ztd W n tk
r0   td Y nX dD ]T}tj|r6zt|d}W n t	k
rh   Y q6X | | j
|  W 5 Q R X q6| S )zR
    Wrap an instance of C{pdb.Pdb} with readline support and load any .rcs.

    r,   zreadline module not available)z.pdbrcZpdbrcr*   )r   ZPdbr   ImportErrorrv   r4   r5   existsr+   rF   ZrcLinesr   	readlines)Zdbgr5   ZrcFiler'   r'   r(   _wrappedPdb  s    r   c                   @   s   e Zd ZdZdS )_DebuggerNotFoundzk
    A debugger import failed.

    Used to allow translating these errors into usage error messages.

    N)r   r   r   r   r'   r'   r'   r(   r   #  s   r   c                 C   s  t j}| d | d | d | d | d | d d}| d rFt jj|d	< n| d
 rxddlm} |}| d
 |d< |  |d< n| d rt jj|d	< | d }|dkrzt||d< W q tj	k
r   t
d|f Y qX n
t |d< | d |d< | d |d< | d |d< |f |S )z
    Return a trial runner class set up with the parameters extracted from
    C{config}.

    @return: A trial runner instance.
    @rtype: L{runner.TrialRunner} or C{DistTrialRunner} depending on the
        configuration.
    r   r   rX   rZ   rd   ra   )ZreporterFactoryZtracebackFormatZrealTimeErrorsZuncleanWarningsrd   ZworkingDirectoryr   moder   r   )DistTrialRunnerZworkerNumberZworkerArgumentsr   r   r   z%r debugger could not be found.r\   Z	exitFirstr   r[   ZforceGarbageCollection)r   ZTrialRunnerZDRY_RUNZtwisted.trial._dist.disttrialr   r   DEBUGr   r   ZModuleNotFoundr   r   )r   clsr   r   r   r'   r'   r(   _makeRunner-  s<    	
r   c               
   C   s&  t tjdkrtjd t } z|   W n: tjk
rf } ztdtjd |f W 5 d }~X Y nX t	|  zt
| }W n< tk
r } ztdtjd t|f W 5 d }~X Y nX t| }| d r||}n
||}| jrtd  | j }|jdd|  jd t|   d S )Nr   z--helpz%s: %sr   r   F)Zshow_missingZsummaryrw   )r   rn   ro   r   ri   ZparseOptionsr   error
SystemExitr   r   r   r   r   ZrunUntilFailurerunr{   r|   resultsZwrite_resultsrw   r5   r   ZwasSuccessful)r   ZueZtrialRunnerrY   ZsuiteZtest_resultr   r'   r'   r(   r   Z  s.    (,


r   )6Z
__future__r   r   r   r   rE   r4   r   r_   rn   r   r   Ztwisted.internetr   Ztwisted.applicationr   Ztwisted.pythonr   r   r	   Ztwisted.python.filepathr
   Ztwisted.python.reflectr   Ztwisted.python.compatr   Ztwistedr   Ztwisted.trialr   r   r   r   r)   r0   r3   r9   rA   rJ   r   rO   rR   objectrS   ri   ZReactorSelectionMixinr   r   r   r   	Exceptionr   r   r   r'   r'   r'   r(   <module>   s^   

!
 k`	
-