o b|@sdZgdZddlZddlZddlZddlZddlZddlZddlZddl Z ddl m Z ddl m Z ddlmZddlmZmZmZmZmZddlmZmZdd lmZmZdd lmZdd lmZdd l m!Z!m"Z"dd l#m$Z$e%dZ&ddZ'ddZ(ddZ)ddZ*ddZ+ddZ,ddZ-Gddde$Z.dZ/Gd d!d!e$Z0Gd"d#d#e$Z1d$d%Z2d&d'Z3e eGd(d)d)Z4Gd*d+d+e4Z5Gd,d-d-Z6d.d/Z7Gd0d1d1Z8dS)2zK A miscellany of code used to run Trial tests. Maintainer: Jonathan Lange ) TestSuiteDestructiveTestSuite ErrorHolder LoggedSuite TestHolder TestLoader TrialRunner TrialSuitefilenameToModule isPackageisPackageDirectory isTestCasenamesamefile NOT_IN_TESTN)SourceFileLoader) implementer)defer)failurefilepathlogmodulesreflect)unittestutil) _ForceGarbageCollectionDecorator _iterateTests) _logObserver) ITestCase)UncleanWarningsReporterWrapper _ExitWrapper)rrcCs2t|tjsdStjtj|jd}|dkS)z>Given an object return True if the object looks like a packageFr__init__) isinstancetypes ModuleTypeospathsplitextbasename__file__)moduler(r+6/usr/lib/python3/dist-packages/twisted/trial/runner.pyr 8s r cCs>dd}|D]}d|}tjtj||r|SqdS)z Is the directory at path 'dirname' a Python package directory? Returns the name of the __init__ file (it may have a weird extension) if dirname is a package directory. Otherwise, returns False cSs tjSN) importlib machinery all_suffixesr+r+r+r, _getSuffixesG z(isPackageDirectory.._getSuffixesr!F)r%r&existsjoin)dirnamer1extinitFiler+r+r,r @s r cCstj|tj|kS)z A hacky implementation of C{os.path.samefile}. Used by L{filenameToModule} when the platform doesn't provide C{os.path.samefile}. Do not use this. )r%r&abspath) filename1 filename2r+r+r,rQsrc Cs|}dtjkr dkrnntj|stjt|}tj|s+t|dt |}zt |}Wntt fyHt ||dYSwt|dddurWt ||dStj|jdd}ttjd t}tj|r|||stj|j=t ||d}|S) aV Given a filename, do whatever possible to return a module object matching that file. If the file in question is a module in Python path, properly import and return that module. Otherwise, load the source manually. @param fn: A filename. @return: A module object. @raise ValueError: If C{fn} does not exist. ))r; z doesn't exist) moduleNamer)Nrz.pyr)sys version_infor%r&isabsr4getcwdr3 ValueErrorrfilenameToModuleNamenamedAnyAttributeError_importFromFilegetattrr'r)risfiler__name__)fnoldFnr>retretFilesamer+r+r,r Ys& &     r cCs|t|}|stjtj|dd}|tjvrtj|Stj ||}|s+t |tj |}|j ||tj|<|S)Nr)_resolveDirectoryr%r&r'splitr?rr.rspec_from_file_location SyntaxErrormodule_from_specloader exec_module)rKr>specr*r+r+r,rGs     rGcCs<tj|rt|}|rtj||}|St|d|S)Nz is not a package directory)r%r&isdirr r4rC)rKr7r+r+r,rQs rQcCsHt|j|jt|kr!t|jD]}t|j|t|kr |Sq|jS)z Find the attribute name on the method's class which refers to the method. For some methods, notably decorators which have not had __name__ set correctly: getattr(method.im_class, method.__name__) != method )rHim_classrJobjectdir)methodaliasr+r+r,_getMethodNameInClasss r_c@seZdZdZddZdS)rzQ A test suite which remove the tests once run, to minimize memory usage. cCs0|jr|jr |S|jd}|||js|S)zn Almost the same as L{TestSuite.run}, but with C{self._tests} being empty at the end. r)_tests shouldStoppop)selfresulttestr+r+r,runs zDestructiveTestSuite.runN)rJ __module__ __qualname____doc__rfr+r+r+r,rs rz cs eZdZdZfddZZS)rz[ Any errors logged in this suite will be reported to the L{TestResult} object. csJt}|t|||D] }|tt|q| dS)z Run the suite, storing all errors in C{result}. If an error is logged while no tests are running, then it will be added as an error to C{result}. @param result: A L{TestResult} object. N) r_addsuperrf_remove getErrorsaddErrorrr flushErrors)rcrdobservererror __class__r+r,rfs   zLoggedSuite.run)rJrgrhrirf __classcell__r+r+rrr,rsrcs2eZdZdZd fdd ZddZdd ZZS) rz Suite to wrap around every single test in a C{trial} run. Used internally by Trial to set up things necessary for Trial tests to work, regardless of what context they are run in. r+FcsF|rg}|D] }t|t}||q|}t|}t|gdSr-)rdecoraterappendrrkr!)rctestsforceGarbageCollectionnewTestsresuiterrr+r,r!s  zTrialSuite.__init__csHddlm}t|ddfdd|dtddS)Nr)reactoraftershutdowncs dSr-)callbackr+dr+r, z"TrialSuite._bail..mktemp) twisted.internetr{rDeferredaddSystemEventTriggerfireSystemEventrTestCase_wait)rcr{r+rr,_bails  zTrialSuite._bailcCs&z t||W|dS|wr-)rrfrrcrdr+r+r,rfszTrialSuite.run)r+F)rJrgrhrir!rrfrtr+r+rrr,rs   rcCs@t|r t|}|Sz|}W|Sty|j}Y|Sw)z @param thing: an object from modules (instance of PythonModule, PythonAttribute), a TestCase subclass, or an instance of a TestCase. )r rqualidrFr )thingtheNamer+r+r,r s    r cCs$zt|tjWStyYdSw)z @return: C{True} if C{obj} is a class that contains test cases, C{False} otherwise. Used to find all the tests in a module. F) issubclasspyunitr TypeError)objr+r+r,r s  r c@sDeZdZdZdZddZddZddZd d Zd d Z d dZ dS)rz Placeholder for a L{TestCase} inside a reporter. As far as a L{TestResult} is concerned, this looks exactly like a unit test. NcCs ||_dS)zM @param description: A string to be displayed L{TestResult}. N description)rcrr+r+r,r!,s zTestHolder.__init__cCs ||Sr-rfrr+r+r,__call__2r2zTestHolder.__call__cC|jSr-rrcr+r+r,r5z TestHolder.idcCsdS)Nrr+rr+r+r,countTestCases8szTestHolder.countTestCasescCs"||||||dS)z This test is just a placeholder. Run the test successfully. @param result: The C{TestResult} to store the results in. @type result: L{twisted.trial.itrial.IReporter}. N) startTest addSuccessstopTestrr+r+r,rf;s  zTestHolder.runcCrr-rrr+r+r,shortDescriptionFrzTestHolder.shortDescription) rJrgrhrifailureExceptionr!rrrrfrr+r+r+r,r#s rcs6eZdZdZfddZdefddZddZZS) ra Used to insert arbitrary errors into a test suite run. Provides enough methods to look like a C{TestCase}, however, when it is run, it simply adds an error to the C{TestResult}. The most common use-case is for when a module fails to import. cst|t||_dS)a+ @param description: A string used by C{TestResult}s to identify this error. Generally, this is the name of a module that failed to import. @param error: The error to be added to the result. Can be an `exc_info` tuple or a L{twisted.python.failure.Failure}. N)rkr!rexcInfoOrFailureToExcInforq)rcrrqrrr+r,r!Rs zErrorHolder.__init__returncCsd|j|jdS)Nz))formatrrqrr+r+r,__repr__]szErrorHolder.__repr__cCs&|||||j||dS)z Run the test, reporting the error. @param result: The C{TestResult} to store the results in. @type result: L{twisted.trial.itrial.IReporter}. N)rrnrqrrr+r+r,rfcs zErrorHolder.run) rJrgrhrir!strrrfrtr+r+rrr,rJs   rc@seZdZdZdZdZddZddZdd Zd&d d Z d dZ e Z ddZ e Z ddZddZddZd&ddZddZd'ddZd&ddZeZd&d d!Zd"d#Zd&d$d%ZdS)(ra4 I find tests inside function, modules, files -- whatever -- then return them wrapped inside a Test (either a L{TestSuite} or a L{TestCase}). @ivar methodPrefix: A string prefix. C{TestLoader} will assume that all the methods in a class that begin with C{methodPrefix} are test cases. @ivar modulePrefix: A string prefix. Every module in a package that begins with C{modulePrefix} is considered a module full of tests. @ivar forceGarbageCollection: A flag applied to each C{TestCase} loaded. See L{unittest.TestCase} for more information. @ivar sorter: A key function used to sort C{TestCase}s, test classes, modules and packages. @ivar suiteFactory: A callable which is passed a list of tests (which themselves may be suites of tests). Must return a test suite. retest_cCst|_t|_g|_dSr-)r suiteFactoryr sorter _importErrorsrr+r+r,r!s zTestLoader.__init__cCst||jdS)zt Sort the given things using L{sorter}. @param xs: A list of test cases, class or modules. )key)sortedr)rcxsr+r+r,sortszTestLoader.sortcCs4g}t|D] \}}t|r||q||S)z-Given a module, return all Trial test classes)inspect getmembersr rvr)rcr*classesr valr+r+r,findTestClassess   zTestLoader.findTestClassesFc Csbtj|vr!t|}zt|Wnty |j||dYSw|}d}}}t|D]B\}}z t|}|}Wn4tyot d} | j durU| j } | j dusM| j j j} | tjkr`|dkrmtd|dYq-w|durt|}|dtd|jdd}z|D] } |t|| }}qWntyt|dw|j||||d S) a Find and load tests, given C{name}. @param _name: The qualified name of the thing to load. @param recurse: A boolean. If True, inspect modules within packages within the given package (and so on), otherwise, only inspect modules in the package itself. @return: If C{name} is a filename, return the module. If C{name} is a fully-qualified Python name, return the object it refers to. recurseNz The module z does not exist..r)parentqualNamer)r%seprrD __import__ ImportErrorloadFile_qualNameWalker namedModuler?exc_infotb_nexttb_framef_code co_filenamer)ModuleNotFoundrErRlenrJrHrF loadAnything) rc_namerr rr remaining searchName remainingNametbfilenameWhereHappenedpartr+r+r, findByNamesN           " zTestLoader.findByNamecCst|tjs t|dt|dr|St|dr|S|}||D] }| | |q(t|ds:|S|}|j D] }| | |qA|||gS)a Return a test suite with all the tests from a module. Included are TestCase subclasses and doctests listed in the module's __doctests__ module. If that's not good for you, put a function named either C{testSuite} or C{test_suite} in your module that returns a TestSuite, and I'll use the results of that instead. If C{testSuite} and C{test_suite} are both present, then I'll use C{testSuite}. z is not a module testSuite test_suite __doctests__) r"r#r$rhasattrrrrraddTest loadClassr loadDoctests)rcr*rz testClassdocSuitedocTestr+r+r, loadModules     zTestLoader.loadModulecs\tts tdtstd}fdd|D}|S)z Given a class which contains test cases, return a list of L{TestCase}s. @param klass: The class to load tests from. z is not a classz is not a test casecsg|] }j|qSr+) _makeCase methodPrefix).0r klassrcr+r, sz(TestLoader.loadClass..)r"typerr rCgetTestCaseNamesrr)rcrnamesrwr+rr,rs   zTestLoader.loadClasscCst||jS)z Given a class that contains C{TestCase}s, return a list of names of methods that probably contain tests. )rprefixedMethodNamesr)rcrr+r+r,r%szTestLoader.getTestCaseNamescCstd)NzCan't happen on Py3)NotImplementedError)rcr]r+r+r, loadMethod,zTestLoader.loadMethodcCs||Sr-r+)rcr methodNamer+r+r,r/rzTestLoader._makeCasec Cst|s t|dt|j}|r|}n|}g}|D]}|jdd |j r3| |q | }| |D]$}z|} WntyVt|jt} Ynw|| } || q=|S)a Load tests from a module object representing a package, and return a TestSuite containing those tests. Tests are only loaded from modules whose name begins with 'test_' (or whatever C{modulePrefix} is set to). @param package: a types.ModuleType object (or reasonable facsimile obtained by importing) which may contain tests. @param recurse: A boolean. If True, inspect modules within packages within the given package (and so on), otherwise, only inspect modules in the package itself. @raise TypeError: If C{package} is not a package. @return: a TestSuite created with my suiteFactory, containing all the tests. z is not a packagerrP)r rr getModulerJ walkModules iterModulesr rR startswith modulePrefixrvrrload BaseExceptionrrFailurerr) rcpackagerpkgobj discovery discovereddiscorzmodinfor* thingToAddr+r+r, loadPackage2s*       zTestLoader.loadPackagecCsxt|trzt|}Wntyt|tYSwt |s)t ddSi}dd}||d<t j |fi|S)z Return a suite of tests for all the doctests defined in C{module}. @param module: A module object or a module name. z&trial only supports doctesting modulesNcSs t|d|j|_|j|_dS)z Save C{test.globs} and replace it with a copy so that if necessary, the original will be available for the next test run. _savedGlobalsN)rHglobsrcopy)rer+r+r, saveGlobalsmsz,TestLoader.loadDoctests..saveGlobalssetUp)r"rrrErrrrrismodulewarningswarndoctest DocTestSuite)rcr* extraArgsrr+r+r,r\s     zTestLoader.loadDoctestsNcCst|tjrt|r|j||dS||St|tr&t|tj r&| |St|tj rLt|trLt|tj rL|d}||}t ||j j|ksJJ|St|trS|Std|)a Load absolutely anything (as long as that anything is a module, package, class, or method (with associated parent class and qualname). @param obj: The object to load. @param recurse: A boolean. If True, inspect modules within packages within the given package (and so on), otherwise, only inspect modules in the package itself. @param parent: If C{obj} is a method, this is the parent class of the method. C{qualName} is also required. @param qualName: If C{obj} is a method, this a list containing is the qualified name of the method. C{parent} is also required. @return: A C{TestCase} or C{TestSuite}. rrPz"don't know how to make test from: )r"r#r$r rloadTestsFromModulerrrrloadTestsFromTestCase FunctionTyperH_testMethodName__func__rr)rcrrrrr instr+r+r,rys&      zTestLoader.loadAnythingc CsBz ||j||dgWSty |t|tgYSw)a* Load some tests by name. @param name: The qualified name for the test to load. @param recurse: A boolean. If True, inspect modules within packages within the given package (and so on), otherwise, only inspect modules in the package itself. r)rrrrrr)rcr rr+r+r, loadByNames   zTestLoader.loadByNamec Csjg}g}|D]!}z ||j||dWqty'|t|tYqw|||||S)a+ Load some tests by a list of names. @param names: A L{list} of qualified names. @param recurse: A boolean. If True, inspect modules within packages within the given package (and so on), otherwise, only inspect modules in the package itself. r) rvr rrrrextendr _uniqueTests)rcrrthingserrorsr r+r+r, loadByNamess   zTestLoader.loadByNamesccsFt}|D]}|j}|D]}t||vr|V|t|q qdS)a  Gather unique suite objects from loaded things. This will guarantee uniqueness of inherited methods on TestCases which would otherwise hash to same value and collapse to one test unexpectedly if using simpler means: e.g. set(). N)setr`radd)rcrseen testthing testthingsrr+r+r,r s zTestLoader._uniqueTestscCsFt|}zt||}|j||dWSty"t|dw)a1 Load a file, and then the tests in that file. @param fileName: The file name to load. @param recurse: A boolean. If True, inspect modules within packages within the given package (and so on), otherwise, only inspect modules in the package itself. rz is not a Python file.)rrDr load_modulerOSErrorrC)rcfileNamerr r*r+r+r,rs  zTestLoader.loadFileF)FNN)rJrgrhrirrr!rrrrrrrrrrrrrr loadTestsFromNamerr rr+r+r+r,ros. V *  0 rccsR|gfV|d}tdt|D]}d|d| || dfVqdS)a3 Given a Python qualified name, this function yields a 2-tuple of the most specific qualified name first, followed by the next-most-specific qualified name, and so on, paired with the remainder of the qualified name. @param qualName: A Python qualified name. @type qualName: L{str} rrN)rRrangerr4)r qualPartsindexr+r+r,rs  &rc @seZdZdZdZdZddZddZeZ dd Z d d e j d d d d d d d d f ddZ ddZddZddZdddZddZd S)rz= A specialised runner that the trial front end uses. debugzdry-runcCs<|t}t|j}t|\}|_t |j |Sr-) _tearDownLogFiler%rBrFilePathworkingDirectoryr_unusedTestDirectory _testDirLockchdirr&)rc currentDirbasetestdirr+r+r, _setUpTestdir s   zTrialRunner._setUpTestdircCst||jdSr-)r%r$r#unlock)rcoldDirr+r+r,_tearDownTestdirs zTrialRunner._tearDownTestdircCs8||j|j|j|j}|jrt|}|jrt|}|Sr-) reporterFactorystreamtbformatrterrors_log _exitFirstr uncleanWarningsr)rcreporterr+r+r, _makeResultszTrialRunner._makeResultNztest.logFdefaultc Cst||_||_||_||_||_||_||_d|_| pd|_d|_ d|_ | |_ | |_ | |_ |r8t|jd|_dSdS)N _trial_tempz profile.data)r,logfilemoder-r.r/r2_resultr!_logFileObserver_logFileObject_forceGarbageCollectiondebuggerr1rprofiledrf) rcr,r8r7r-profiletracebackFormatrealTimeErrorsr2r!rxr= exitFirstr+r+r,r!#s" zTrialRunner.__init__cCs@|jdurt|jjd|_|jdur|jd|_dSdSr-)r:rremoveObserveremitr;closerr+r+r,rCs    zTrialRunner._tearDownLogFilecCsL||jdkr tj}nt|jd}||_t||_t |jj ddS)N-ar) rr7r?stdoutopenr;rFileLogObserverr:startLoggingWithObserverrD)rclogFiler+r+r, _setUpLogFileKs   zTrialRunner._setUpLogFilecCst|t}|||jS)zC Run the test or suite and return a result object. )rrur_runWithoutDecorationr<)rcrer+r+r,rfUs zTrialRunner.runc sFt|g|t}jjkr+tD]}|||qn7jj kr:fdd}nfdd} }z |W  |n   |wt}tdd}|durtjdtjtddjd j||d SS) zR Private helper that runs the given test but doesn't decorate it. csjjSr-)r=runcallrfr+rdrcrzr+r,rmsz3TrialRunner._runWithoutDecoration..cs Sr-rr+)rdrzr+r,rordoneNzR%s should implement done() but doesn't. Falling back to printErrors() and friends.r;)category stacklevelzRan %d tests in %.3fs )r4rtimer8DRY_RUNrrrrDEBUGr(rMrr+rHrrrrrsDeprecationWarning printErrorswriteln separatortestsRunwrite printSummaryrQ) rcrerx startTimesinglerfr*endTimerQr+rPr,rN\sP              z!TrialRunner._runWithoutDecorationcCs^d} |d7}|jd|f|dkr||}n||}|jdkr' |S|s. |Sq)z8 Repeatedly run C{test} until it fails. rTrz Test Pass %d )r-r]rfrNr\ wasSuccessful)rcrecountrdr+r+r,runUntilFailures   zTrialRunner.runUntilFailurer)rJrgrhrirWrVr(r+rr0r4r?rHr!rrMrfrNrdr+r+r+r,rs2     1r)9ri__all__rr.rr%r?rUr#rimportlib.machineryrzope.interfacerrrtwisted.pythonrrrrr twisted.trialrrtwisted.trial._asyncrunnerrrtwisted.trial._synctestrtwisted.trial.itrialrtwisted.trial.reporterrr twisted.trial.unittestrrrr r rr rGrQr_rrrrr r rrrrrr+r+r+r,sV      1 $ &%