3 JZL@sdZddlmZddlZddlZddlZddlZddlZddlZddl Z ddl Z ddl Z ddl Z ddl Z ddlZddlZddlZddlZddlZddlZddlZddlZddlZddl mZddl mZddl mZddl mZddlZddlmZdd lmZdd lmZdd lmZdd l m!Z!dd l"m#Z#ddl"m$Z$ddl"m%Z%ddl"m&Z&ej'dkrjddl(Z)nddl)Z)yddl)m*Z*Wne+k rddl*Z*YnXej'dkrddl,Z,ndZ,ddddddddddd d!d"d#d$d%d&d'd(d)d*d+d,d-d.d/d0d1d2d3d4d5d6d7d8d9d:d;dd?d@dAdBdCdDdEdFdGdHdIdJdKdLdMdNdOdPdQdRdSdTdUdVdWdXdYgDZ-ej.d"pZdZdkZ/d]ej0kZ1erpdndZ2e3ej4j5d#Z6e3ej4j5dZ7d_Z8dZ9dZ:ej.dbse/rdcndZ;e6se7re8d9Z8e:d9Z:ddZej=j?ej@e<ZAeAdeZBeAe$dfZCejDjEdkZFej=jGej=j>ej=jHeIdidiZJej=j>eJdjZKej=jGej=jHeIZLeMejNdkZOeMedlZPeoze ZQeMejNdmZReMejNdnZSeMejNdoZTdpejNjUjVkZWeMejNdqZXeMejNdrZYeMejNdsZZeMejNdtZ[eMeduZ\e\oej]Z^eMedvZ_eMedwZ`dxdyZaeaZbecejddzZed{d|efeDZgehe d}eiZjehe d~eiZkelZmelZnelZoejpddZqejpddZrGdddejsZtddZueuddd5Zveudd7Zwdd6Zxeudd3ZyeuddZzddd4Z{ddHZ|ddGZ}GdddeiZ~e~ejde:ddddJZe~eefde:dddddKZe~ede:ddddIZddBZddZejddAZdddCZeZdd<Ze8fdd;Zddd9Zddd:ZdddNZejdddOZeedfddPZe jfddQZdddRZddSZejddTZddMZddLZddUZddVZddWZddYZereje.attemptz python%s.%srz"can't find python exe real abspath)rsys executableospathrealpathr version_infopsutilProcessrf ValueErrorexistsAssertionError)rirfrgrgrh _get_py_exes  ruzr+cCs g|]}|jdrtt|qS)ZSTATUS_) startswithgetattrrp).0xrgrgrh srzAF_UNIXSOCK_SEQPACKETc CstjxbtjtdD]P}t|tr0tt}nt}|j|ry t |Wqt k rft j YqXqWx6t D].}y t |Wqrt k rt j YqrXqrWdS)N.)rcloserllistdirr isinstancerrrvr>re traceback print_exc_testfiles_created)nameprefixrmrgrgrh_cleanup_filess      rcCstdddS)NT) recursive)r3rgrgrgrh_cleanup_procssrc@sHeZdZdZddZddZddZdd Zd d Zd d Z ddZ dS) ThreadTaskz6A thread task which does nothing expect staying alive.cCs&tjj|d|_d|_tj|_dS)NFgMbP?) threadingThread__init___running _intervalZEvent_flag)selfrgrgrhrs zThreadTask.__init__cCs|jj}d||jt|fS)Nz<%s running=%s at %#x>) __class____name__rid)rrrgrgrh__repr__szThreadTask.__repr__cCs |j|S)N)start)rrgrgrh __enter__szThreadTask.__enter__cOs |jdS)N)stop)rargskwargsrgrgrh__exit__szThreadTask.__exit__cCs(|jrtdtjj||jjdS)zStart thread and keep it running until an explicit stop() request. Polls for shutdown every 'timeout' seconds. zalready startedN)rrrrrrrwait)rrgrgrhrs zThreadTask.startcCs,d|_|jjx|jr&tj|jqWdS)NT)rrsettimesleepr)rrgrgrhrun s zThreadTask.runcCs |jstdd|_|jdS)z8Stop thread execution and and waits until it is stopped.zalready stoppedFN)rrrjoin)rrgrgrhrszThreadTask.stopN) r __module__ __qualname____doc__rrrrrrrrgrgrgrhrs rcstjfdd}|S)Nc s,y ||Stk r&tYnXdS)N)rer3)rr)funrgrhwrappers  z _cleanup_on_err..wrapper) functoolswraps)rrrg)rrh_cleanup_on_errsrcKs|jdt|jdt|jdtj|jdtjtrF|jdd|dkrttdt}td |g}t j |f|}t j |t td d d n"t j |f|}t j |t|j|S) a{Creates a python subprocess which does nothing for 60 secs and return it as subprocess.Popen instance. If "cmd" is specified that is used instead of python. By default stdin and stdout are redirected to /dev/null. It also attemps to make sure the process is in a reasonably initialized state. The process is registered for cleanup on reap_children(). stdinr`cwdenv creationflagsiNz:from time import sleep;open(r'%s', 'w').close();sleep(60);z-cT)deleteempty) setdefaultrrlgetcwdr]r r>_TESTFNrrbPopen_subprocesses_startedaddrErDpid)cmdkwdsZpylineZsprocrgrgrhr4)s$       cCstjjtd}tjd|tf}tr4t|dd}nt|}t j |j }t |ddd}tj |t|}tj|t j |}||fS)aCreate a subprocess which creates another one as in: A (us) -> B (child) -> C (grandchild). Return a (child, grandchild) tuple. The 2 processes are fully initialized and will live for 60 secs and are registered for cleanup on reap_children(). 2a import subprocess, os, sys, time s = "import os, time;" s += "f = open('%s', 'w');" s += "f.write(str(os.getpid()));" s += "f.close();" s += "time.sleep(60);" subprocess.Popen(['%s', '-c', s]) time.sleep(60) r)rF)rr)rlrmbasenamertextwrapdedentrr r2rprqrrEremoveint _pids_startedr)Z_TESTFN2ssubpZchild1dataZ child2_pidZchild2rgrgrhr6Js     cstjs ttrtjtdnt}tj d|}t j t j t j }|jt|j||jdt||j\}}zNtj|jgggtt|jd}tj|tj|tfddd|S|jXWdQRXdS) z+Create a zombie process and return its PID.)ra import os, sys, time, socket, contextlib child_pid = os.fork() if child_pid > 0: time.sleep(3000) else: # this is the zombie process s = socket.socket(socket.AF_UNIX) with contextlib.closing(s): s.connect('%s') if sys.version_info < (3, ): pid = str(os.getpid()) else: pid = bytes(str(os.getpid()), 'ascii') s.sendall(pid) rYicsjS)N)statusrg)zprocrgrhsz$create_zombie_proc..zret == psutil.STATUS_ZOMBIEN)rprrtrtempfilemktemprrrr contextlibclosingsocketr{Z settimeoutrbindlistenr2acceptselectfilenorZrecvrrrqrCr~)Z unix_filesrcsockconn_Zzpidrg)rrhr5ms$        c Ksr|jdd|jddtjtddd@}tj|j|j||jt t |jgf|}t |j WdQRX|S)zeRun python 'src' code string in a separate interpreter. Returns a subprocess.Popen instance. r`NrawtF)rmoder) rrNamedTemporaryFilerrrrwriteflushr4rrDr)rrfrrgrgrhr2s    cKst|ttfrdnd}tr"|r"dnd}|jd||jdtj|jdtj|jdd|jd |tj|f|}tj ||j \}}|j dkrt ||rt ||jd r|d d }|S)zUrun cmd in a subprocess and return its output. raises RuntimeError on error. TFirshellr`raZuniversal_newlinesr NrY)rstrrr rrbrdrrrZ communicate returncode RuntimeErrorrQendswith)rrrflagspr`rargrgrhshs"        rFc 'Cs*dd}|r"ttjjdd}nt}xtrtj}tj|jy |j Wn0t k r~}z|j t j krnWYdd}~XnX|j r|j j|jr|jjz|jr|jjWdy |jWn0t k r}z|j t jkrWYdd}~XnXXq*WxLtrFtj}ytj|}Wn tjk r8||YqX|j|qW|r&x4|D],}y |j Wntjk r|YnXqTWtj|td\}}x@|D]8}td|y |jWntjk rYnXqWtj|td\}}|r x|D]}td|qWx|D]}||jqWdS) a#Terminate and wait() any subprocess started by this test suite and ensure that no zombies stick around to hog resources and create problems when looking for refleaks. If resursive is True it also tries to terminate and wait() all grandchildren started by this process. c Ssttj| st||tjks(t|y tj|}|j sFt|Wntjk r^YnXdsptd|dS)Nrzpid %s is not gone)rpZ pid_existsrtZpidsrqZ is_running NoSuchProcess)rrrgrgrh assert_gones z"reap_children..assert_goneT)rN)timeoutz0couldn't terminate process %r; attempting kill()zprocess %r survived kill())rrprqchildrenrpoprrrZ terminateOSErrorerrnoZESRCHr`r~rarrZECHILDrZ wait_procsrrQkill) rrrrerrrrZgonealivergrgrhr3sd                 cCsts tdd}tjd}x(|D] }|js6|dkr@||7}q"Pq"W|sVtd|d}d}|jd}t|d}t|dkrt|d}t|dkrt|d}|||fS) z"Return a tuple such as (2, 6, 36).z not POSIXrTrr}zcan't parse %rrrYr) rNotImplementedErrorrlunameisdigitrrsplitrlen)rrcminormicroZnumsmajorrgrgrhrBs&          cCsdts tdtj}t|dr*|jp&d}n(tjd|d}|rNt|j d}nd}|d|d|fS)Nz not WINDOWSservice_pack_majorrz\s\d$rrY) r rrjZgetwindowsversionhasattrrresearchrgroup)ZwvZsprrgrgrhrA3s  c@s@eZdZdZedddddfddZdd Zd d Zd d ZdS)retryzA retry decorator.NgMbP?cCst|tjdS)N)file)printrjra)rrgrgrhrOszretry.cCs2|r|rtd||_||_||_||_||_dS)Nz/timeout and retries args are mutually exclusive)rr exceptionrretriesintervallogfun)rrrrrrrgrgrhrJszretry.__init__ccs`|jr.tj|j}xFtj|kr*dVqWn.|jrPx&t|jD] }dVq@Wn x dVqRWdS)N)rrrrange)rZstop_atrrgrgrh__iter__Ys  zretry.__iter__cCs|jdk rtj|jdS)N)rrr)rrgrgrhres z retry.sleepcs"tjfdd}|_|S)Ncstd}x^D]V}y ||Sjk r^}z(|}jdk rDj|jw WYdd}~Xq Xq Wtrn|ndS)N)rrrr )rrexcr)rrrgrhrjs    zretry.__call__..wrapper)rr decorator)rrrrg)rrrh__call__iszretry.__call__) rrrrrerrrrrgrgrgrhrGs  rgMbP?)rrrrcCstj|trtjddS)zWait for pid to show up in the process list then return. Used in the test suite to give time the sub process to initialize. g{Gz?N)rprqr rr)rrgrgrhrDs Tc Cs<t|d}|j}WdQRX|s*|s*t|r8tj||S)z8Wait for a file to be written on disk with some content.rbN)openreadrtrlr)ZfnamerrrrrgrgrhrEs  cCs|}t|st|S)zVKeep calling function for timeout secs and exit if eval() expression is True. )evalrt)rexprretrgrgrhrCs cCsfy0tj|}tj|jr$tj|n tj|Wn0tk r`}z|jtjkrPWYdd}~XnXdS)z>Convenience function for removing temporary test files or dirsN) rlstatS_ISDIRst_modermdirrrrENOENT)rmstrrgrgrhr>s    cCsDytj|Wn0tk r>}z|jtjkr.WYdd}~XnXdS)z-Convenience function for creating a directoryN)rlmkdirrrZEEXIST)dirrrgrgrh safe_mkdirs  rc cs.tj}ztj|dVWdtj|XdS)z@Context manager which temporarily changes the current directory.N)rlrr=)dirnamecurdirrgrgrhr=s   cCstjj| st||rtds*tdt|tr>tj d}t|t sPt|t j dddd}|j |WdQRXztjd|jd |gWdt|jXn.tjt|trtj|}tj||jtjBdS) z1Creates an executable file in the given location.gcczgcc is not installedz #include int main() { pause(); return 1; } z.cFr)suffixrrNz-o)rlrmrsrtrrrrboolrrrrrrrbrcrr>shutilcopyfilerrrchmodrS_IEXEC)ZoutpathZc_coderrrgrgrhr?s$   cCstj||dS)N)rr)rr)rrrgrgrhr@sc@s(eZdZddZeejds$ejjZdS)TestCasecCsd|jj|jj|jfS)Nz%s.%s.%s)rrrZ_testMethodName)rrgrgrh__str__s zTestCase.__str__assertRaisesRegexN) rrrr!runittestr ZassertRaisesRegexpr"rgrgrgrhr s r cCs$dtjkrdtjd<tjjjdS)NZPSUTIL_TESTINGrU)rlr]rpZ _psplatformZcextZ set_testingrgrgrgrh _setup_testss  r$cCs`ddtjtD}dtjkr,dd|D}tj}x&|D]}d|}|jtjj|q:W|S)NcSs<g|]4}|jdr|jdr|jd rtjj|dqS)z.pyZtest_Ztest_memory_leaksr)rrvrlrmsplitext)rxryrgrgrhrzszget_suite..ZWHEELHOUSE_UPLOADER_USERNAMEcSsg|]}|jds|qS)osxposixlinux)r&r'r()r)rxryrgrgrhrzszpsutil.tests.%s) rlrHEREr]r# TestSuiteaddTestdefaultTestLoaderloadTestsFromName)ZtestmodssuiteZtmrgrgrhr; s  cCs8ttjtdjt}|j}tj|r.dnddS)N) verbosityrrY) r$r#TextTestRunnerr$rr; wasSuccessfulrjexit)resultsuccessrgrgrhr<scCshttjjtjj|d}tj}|jtjj |tj t dj |}|j }tj|r^dnddS)Nr)r/rY)r$rlrmr%rr#r*r+r,r-r0r$rr1rjr2)rr.r3r4rgrgrhr:#scCsttd|dS)zZDecorator which runs a test function and retries N times before actually failing. N)rrr)rrt)rrgrgrhr9/scsfdd}|S)z,Decorator to Ignore AccessDenied exceptions.cstjfdd}|S)Nc s>y ||Stjk r8dk r*s*tjdYnXdS)Nzraises AccessDenied)rpZ AccessDeniedr#SkipTest)rr)ronly_ifrgrhr9s z9skip_on_access_denied..decorator..wrapper)rr)rr)r6)rrhr8s z(skip_on_access_denied..decoratorrg)r6rrg)r6rhr76s csfdd}|S)z3Decorator to Ignore NotImplementedError exceptions.cstjfdd}|S)Nc sFy ||Stk r@dk r(s(dj}tj|YnXdS)Nz4%r was skipped because it raised NotImplementedError)rrr#r5)rrmsg)rr6rgrhrIs z;skip_on_not_implemented..decorator..wrapper)rr)rr)r6)rrhrHs z*skip_on_not_implemented..decoratorrg)r6rrg)r6rhr8Fs 127.0.0.1c CsFtjtj.}|jtjtjd|j|df|jdSQRXdS)zReturn an unused TCP port.rYrN)rrr setsockopt SOL_SOCKET SO_REUSEADDRr getsockname)hostrrgrgrhrH]sccsJtjs tt|d}z |VWdytj|Wntk rBYnXXdS)zaA context manager which returns a non-existent file name and tries to delete it on exit. )rN)rprrtr@rlunlinkr)rrmrgrgrhrIes   c Cs||dkr|ttfkrd}tj||}y4|jtjtjd|j||tjkrV|jd|St k rv|j YnXdS)zBinds a generic socket.NrTrrYrX)rTr) rrrr9r:r;rrrrer~)familytypeaddrrrgrgrhrJus    c Csttjs ttjj| s t|tjtj|}y"|j||tj krN|j dWnt k rn|j YnX|S)zBind a UNIX socket.rX) rprrtrlrmrsrr{rrrrer~)rr@rrgrgrhrKs   cCstjtj|t}|j||jd|j}tj|t}y@|j||j}x(|j\}}||krn||fS|j qRWWnt k r|j YnXWdQRXdS)z^Build a pair of TCP sockets connected to each other. Return a (server, client) tuple. rXN) rrrrrrr<connectrr~r)r?rAZllrZcaddrargrgrhrLs      c Cstjs td}}y@t|tjd}|jdtjtjtj}|jd|j|Wn6t k r|dk rr|j |dk r|j YnX||fS)zBuild a pair of UNIX sockets connected to each other through the same UNIX file name. Return a (server, client) tuple. N)r@r) rprrtrKrrZ setblockingr{rBrer~)rZserverZclientrgrgrhrMs   c csg}d}}z|jttjtj|jttjtjtrd|jttjtj|jttjtjtrt rt j }t j }t |\}}t |tjd}x|||fD]}|j|qW|VWdx|D] }|jqW|dk rt||dk rt|XdS)z1Open as many socket families / types as possible.N)r@)appendrJrrrrr rrHAS_CONNECTIONS_UNIXrIrrMrKr~r>)ZsocksZfname1Zfname2s1s2Zs3rrgrgrhrNs,      cCsddl}tr$tr$t|tjs$t||tjkrdd|jdD}t |dksVt|x,|D]$}d|kordkns\t|q\Wtst |}|j |nb|tj krt|t st|tst |}|j|n.|tjkrtjd|dk st|n td |dS) z[Check a net address validity. Supported families are IPv4, IPv6 and MAC addresses. rNcSsg|] }t|qSrg)r)rxryrgrgrhrzsz%check_net_address..r}rz([a-fA-F0-9]{2}[:|\-]?){6}zunknown family %r) ipaddressenumr rIntEnumrtrrrrrZ IPv4AddressrrZ IPv6AddressrpZAF_LINKrmatchrr)rAr?rIZoctsZnumrgrgrhrGs&  $    c(Cst|dkst|t|dk}t|dddk}|d|jksBt|d|jksTt|d|jksft|d|jksxt|d|jkst|d |jkst|r|d|j kst|rn|jdkst|t t d ot rnyt j |j|j|j}Wn>t jtfk r2}z|jdtjkr"WYd d }~Xn.)rWrrr)(rrtrwrMr?r@ZladdrZraddrrrrrr rOerrorrrrZEBADFrrrrr{reprrZ EADDRNOTAVAILrpZ CONN_NONErrr|rtupleZportrrGZiprr)rZhas_pidZhas_fdZdupsockrrrAZvalidsrgrgrhrFsf         ( c CsLyddl}t|dstWn"tk r<ddl}|j|SX|j|SdS)z,Backport of importlib.reload of Python 3.3+.rNreload) importlibr ImportErrorimprS)modulerTrVrgrgrhrOFs  cCstjjtjj|d}tjddkr:ddl}|j||Stjdddkrfddlm }|||j Sddl }|j j ||}|j j|}|jj||SdS)Nrrrr)SourceFileLoader)rr)rlrmr%rrjrorVZ load_sourceZimportlib.machineryrX load_moduleimportlib.utilutilspec_from_file_locationmodule_from_specloader exec_module)rmrrVrXrTspecmodrgrgrhrPSs    cCstj|tdS)zRaise a warning msg.N)warningsrQ UserWarning)r7rgrgrhrQhscCsVt|}|j}t|dks&|dtkr*dSt|dd}t|tsDdStdd|DS)z-Check if object is an instance of namedtuple.rYrF_fieldsNcss|]}t|tkVqdS)N)r@r)rxnrgrgrh vsz is_namedtuple..)r@ __bases__rrRrwrall)rytbrrgrgrhrSms  c #sfdtj|d}fddtjjD}tj|}tj||zt j ||VWdt |XdS)zCtx manager which picks up a random shared CO lib used by this process, copies it in another location and loads it in memory via ctypes. Return the new absolutized path. z.so)rrcs6g|].}tjj|jdkrd|jjkr|jqS)rYpython)rlrmr%lower)rxry)extrgrhrzsz'copyload_shared_lib..N) rrrprqr^randomchoicerrctypesZCDLLr>) dst_prefixdstlibsrrg)rmrhrRzs    c #sddlm}ddlm}dtj|d}fddtjjD}tj |}t j ||d}ztj |}|VWd|dk rtj jj}|jg|_||j}|dkr|t|XdS) zCtx manager which picks up a random shared DLL lib used by this process, copies it in another location and loads it in memory via ctypes. Return the new absolutized, normcased path. r)wintypes)WinErrorz.dll)rrcsPg|]H}tjj|jdjkrdtjj|jjkrd|jjkr|jqS)rYrkZwow64)rlrmr%rlr)rxry)rmrgrhrzsz'copyload_shared_lib..N)rprtrurrrprqr^rnrorrZWinDLLZwindllZkernel32 FreeLibraryZHMODULEZargtypesZ_handler>) rqrtrurrrsrcfilervr rg)rmrhrRs$         )rr)rr)rUrV)rWrri)rZr[)N)F)TF)N)N)N)r8)rTrTr)rx)rZ __future__ratexitrrprrrlrnrrrrrrbrjrrrrrrbrrrrrprrr r Zpsutil._commonr Zpsutil._compatr r rrroZ unittest2r#rrUrJ__all__getenvr!builtin_module_namesrZ WIN_VISTArr]getr"rrrrr$rrmrrnrrrr getfilesystemencodingrlZASCII_FSabspathr__file__rrr)rrqr%r&rEr'r(r)Zmemory_full_infordr1r*r+r,Z HAS_THREADSr-r_r.r/r0rurr devnullrrr#rwobjectr{r|rrrrregisterrrrrrr4r6r5r2rr3rBrArrrDEnvironmentErrorrtrErCr>rcontextmanagerr=r?r@r r$r;r<r:r9r7r8rHrIrJrKrLrMrNrGrFrOrPrQrSrRrgrgrgrh sN                                          0  #%   _:             L