o
    a                     @   s4  d Z ddl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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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 ddl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! 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' 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- ddl(m.Z. ddl(m/Z/ ddl(m0Z0 e)rddl1Z1nddl2Z1zddl1m3Z3 W n( e4y   e5  e6d ddl3Z3W d   n	1 sw   Y  Y nw ej7dkr)ddl8Z8ndZ8e!r4ddl9m:Z: g dZ;dej<v Z=de
j>v Z?d e
j>v pLd!e
j>v Z@e?pQe@ZAejBd"kZCd#ZDd$ZEd%ZFd&ZGeArreDd'9 ZDeGd'9 ZGeEd'9 ZEeFd'9 ZFe
jHd(krd)e
I  ZJnd*e
I  ZJe.d+ZKe)rd,Ld-d.ZMnd/ZMeN O d0v ZPe
jQRe
jQSe
jQTeUd1d1ZVe
jQSeVd2ZWe
jQRe
jQTeUZXe!oe" ZYeZej[d3Z\eZed4Z]eZed5Z^eZej[d6Z_eZej[d7Z`eZej[d8ZaeZed9ZbeZej[d:ZceZej[d;ZdeZej[d<ZeeZed=Zfzefoegeh ZiW n ejy   d>ZiY nw eZed?ZkeZed@ZleZej[dAZme s0eo5e
n dkZodBdC Zpep Zqere
jsdDZteuetjv dEdF eweD ZxeyedGez Z{e| Z}e| Z~G dHdI dIejZdJdK ZeddLdMZedNdO ZdPdQ ZedRdS ZedTdU ZejeGfdVdWZddXdYZdZd[ Zd\d] ZG d^d_ d_ezZeejdeGd`dadbdc Zee+efdeGd`daddedfZeedeGd`dadgdh Zdidj Zdkdl Zejdmdn ZddodpZddrdsZG dtdu due1jZee1_G dvdw dweZe1e=dxG dydz dzeZd{d| Zd}d~ ZG dd dZG dd dZdd ZeDfddZdddZdddZdddZeedfddZejfddZdddZdd Zejdd Zdd Zdd Zdd Zdd Zdd Zdd Ze!r{ejdddZnejdddZejudd Ze!reejdd  dS dS )z
Test utilities.
    )print_functionN)AF_INET)AF_INET6)SOCK_STREAM)AIX)FREEBSD)LINUX)MACOS)POSIX)SUNOS)WINDOWS)bytes2human)print_color)supports_ipv6)PY3)FileExistsError)FileNotFoundError)range)super)u)unicode)which)mockignore      )wait_pid)EAPPVEYORDEVNULLGLOBAL_TIMEOUTTOLERANCE_SYS_MEM
NO_RETRIESPYPY
PYTHON_EXEROOT_DIRSCRIPTS_DIRTESTFN_PREFIXUNICODE_SUFFIXINVALID_UNICODE_SUFFIX
CI_TESTINGVALID_PROC_STATUSESTOLERANCE_DISK_USAGEIS_64BITHAS_CPU_AFFINITYHAS_CPU_FREQHAS_ENVIRONHAS_PROC_IO_COUNTERS
HAS_IONICEHAS_MEMORY_MAPSHAS_PROC_CPU_NUM
HAS_RLIMITHAS_SENSORS_BATTERYHAS_BATTERYHAS_SENSORS_FANSHAS_SENSORS_TEMPERATURESZHAS_MEMORY_FULL_INFOpyrun	terminatereap_childrenspawn_testprocspawn_zombiespawn_children_pairZThreadTaskunittestskip_on_access_deniedskip_on_not_implementedretry_on_failureTestMemoryLeakPsutilTestCaseprocess_namespacesystem_namespaceprint_sysinfoZinstall_pipZinstall_test_depschdirsafe_rmpath
create_exeZdecode_pathZencode_path
get_testfn
get_winverkernel_version
call_untilwait_for_pidwait_for_filecheck_net_addressget_free_portbind_socketbind_unix_sockettcp_socketpairunix_socketpaircreate_socketsreload_moduleimport_module_by_pathwarncopyload_shared_libis_namedtupleZ__pypy__r   GITHUB_ACTIONSZCIBUILDWHEELl        
   i  P i      r   javaz$psutil-%s-z@psutil-%s-u   -ƒőős   futf8surrogateescapeu   fÀ)asciizus-asciiz..Zscriptscpu_affinitycpu_freq
getloadavgenvironionicememory_mapsnet_io_counterscpu_numio_countersrlimitsensors_batteryFsensors_fanssensors_temperaturesthreadsc                  C   s   dd } t rtrtrtdS tdS trtjtj	S tdS t
rL| tj	pC| tjtj	pC| tdtjd d  pC| t  }|sJtd|S tjtj	}tj|s]J ||S )	Nc                 S   s4   zt j| dgt jt jd W | S  ty   Y d S w )Nz-V)stdoutstderr)
subprocess
check_callPIPE	Exception)exe ry   7/usr/lib/python3/dist-packages/psutil/tests/__init__.pyattempt   s   z_get_py_exe.<locals>.attemptZpypy3pypypythonzpython%s.%s   z"can't find python exe real abspath)r]   r#   r   r   r   ospathrealpathsys
executabler	   version_infopsutilProcessrx   
ValueErrorexists)r{   rx   ry   ry   rz   _get_py_exe   s*   	
r   zr+c                 C       g | ]}| d rtt|qS )ZSTATUS_
startswithgetattrr   .0xry   ry   rz   
<listcomp>       r   AF_UNIXc                       sP   e Zd ZdZ fddZdd Zdd Zdd	 Zd
d Zdd Z	dd Z
  ZS )
ThreadTaskz6A thread task which does nothing expect staying alive.c                    s$   t    d| _d| _t | _d S )NFMbP?)r   __init___running	_interval	threadingZEvent_flagself	__class__ry   rz   r      s   
zThreadTask.__init__c                 C   s   | j j}d|| jt| f S )Nz<%s running=%s at %#x>)r   __name__r   id)r   namery   ry   rz   __repr__  s   zThreadTask.__repr__c                 C   s   |    | S N)startr   ry   ry   rz   	__enter__  s   zThreadTask.__enter__c                 O   s   |    d S r   )stop)r   argskwargsry   ry   rz   __exit__
  s   zThreadTask.__exit__c                 C   s(   | j rtdtj|  | j  dS )zStart thread and keep it running until an explicit
        stop() request. Polls for shutdown every 'timeout' seconds.
        zalready startedN)r   r   r   Threadr   r   waitr   ry   ry   rz   r     s   zThreadTask.startc                 C   s0   d| _ | j  | j rt| j | j sd S d S )NT)r   r   settimesleepr   r   ry   ry   rz   run  s
   
zThreadTask.runc                 C   s    | j stdd| _ |   dS )z8Stop thread execution and and waits until it is stopped.zalready stoppedFN)r   r   joinr   ry   ry   rz   r     s   zThreadTask.stop)r   
__module____qualname____doc__r   r   r   r   r   r   r   __classcell__ry   ry   r   rz   r      s    	r   c                    s   t   fdd}|S )Nc                     s(   z | i |W S  t y   t   w r   )rw   r<   r   r   funry   rz   wrapper*  s   z&_reap_children_on_err.<locals>.wrapper	functoolswrapsr   r   ry   r   rz   _reap_children_on_err)  s   r   c                 K   s   | dt | dt | dt  | dtj tr%d}| d| | du r[t }z)t| d| }td	|g} t	j
| fi |}t| t|d
d
d W t| |S t| w t	j
| fi |}t| t|j |S )a}  Creates a python subprocess which does nothing for 60 secs and
    return it as a 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().
    stdinrr   cwdenv   creationflagsNz:from time import sleep;open(r'%s', 'w').close();sleep(60);z-cTdeleteempty)
setdefaultr   r   getcwdrg   r   rK   rI   r$   rt   Popen_subprocesses_startedaddrP   rO   pid)cmdkwdsZCREATE_NO_WINDOWtestfnZpylinesprocry   ry   rz   r=   4  s2   





r=   c                  C   s   d} t t d}zItdtj|tf }tr"t	|dd\}} nt	|\}} t
|j}tt|ddd}t| t
|}||fW t| | durRt|  S S t| | dur`t|  w w )	a  Create 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().
    Ndira;              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);"
            p = subprocess.Popen([r'%s', '-c', s])
            p.wait()
            r   )r   TFr   )rK   r   r   textwrapdedentr   basenamer$   r   r:   r   r   r   intrP   _pids_startedr   rI   )tfiler   ssubpchildZgrandchild_pidZ
grandchildry   ry   rz   r?   \  s,   	



r?   c                     s   t jsJ t } td|  }d}t| }zW|t t|\}}|	 \}}z@t

| gg g t t|d}t| t | t fddd | fW |  W |  t|  |durgt| S S |  w |  t|  |dur~t| w w )zCreate a zombie process and return a (parent, zombie) process tuple.
    In order to kill the zombie parent must be terminate()d first, then
    zombie must be wait()ed on.
    a          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)
        N   c                      s      S r   )statusry   zombiery   rz   <lambda>  s    zspawn_zombie.<locals>.<lambda>zret == psutil.STATUS_ZOMBIE)r   r
   rK   r   r   rT   Z
settimeoutr    r:   acceptselectfilenor   Zrecvr   r   r   rN   closerI   )Z	unix_filesrcr   sockparentconn_Zzpidry   r   rz   r>     s<   







r>   c                 K   s   | dd | dd t }z/t|d}||  W d   n1 s%w   Y  tt|jgfi |}t|j ||fW S  t	yJ   t
|  w )zRun python 'src' code string in a separate interpreter.
    Returns a subprocess.Popen instance and the test file where the source
    code was written.
    rr   Nrs   wt)r   rK   openwriter=   r$   r   rO   r   rw   rI   )r   r   srcfilefr   ry   ry   rz   r:     s   

r:   c                 K   s   t | ttfr	dnd}tr|rdnd}|d| |dtj |dtj |dd |d	| tj| fi |}t	| t
rL|jtd
\}}n| \}}|jdkr[t||rat| |drl|dd }|S )zUrun cmd in a subprocess and return its output.
    raises RuntimeError on error.
    TFr   r   shellrr   rs   Zuniversal_newlinesr   timeout
N)
isinstancestrr   r   r   rt   rv   r   r   r   r   Zcommunicater    
returncodeRuntimeErrorrZ   endswith)r   r   r   flagsprr   rs   ry   ry   rz   sh  s&   


r   c              
      s  dd dd   fdd} fddfd	d
}dd }| }zt |trP|||W t |tjtjfr<|| t |trC|n|j}t|rOJ |S t |tjtjfr||W t |tjtjfrk|| t |trr|n|j}t|r~J |S t |tjr|||W t |tjtjfr|| t |tr|n|j}t|rJ |S td| t |tjtjfr|| t |tr|n|j}t|rJ |w )a  Terminate a process and wait() for it.
    Process can be a PID or an instance of psutil.Process(),
    subprocess.Popen() or psutil.Popen().
    If it's a subprocess.Popen() or psutil.Popen() instance also closes
    its stdin / stdout / stderr fds.
    PID is wait()ed even if the process is already gone (kills zombies).
    Does nothing if the process does not exist.
    Return process exit status.
    c                 S   sh   t | tjrts|   n| | tr0t | tjr2z
t| j|W S  tj	y/   Y d S w d S d S r   )
r   rt   r   r   r   r   r   r   r   NoSuchProcessprocr   ry   ry   rz   r     s   

zterminate.<locals>.waitc                 S   s6   t rtrtj}tr|tjkr| tj | | d S r   )r	   r]   signalSIGKILLr
   send_signalSIGCONT)r   sigry   ry   rz   sendsig  s
   zterminate.<locals>.sendsigc              
      s\   z |  W n! t y( } ztr|jdkrn|jtjkr W Y d }~nd }~ww | |S )N   )OSErrorr   winerrorerrnoZESRCH)r   r   errr  r  r   ry   rz   term_subproc   s   
zterminate.<locals>.term_subprocc                    s.   z |  W n
 t jy   Y nw | |S r   )r   r   r   r	  ry   rz   term_psproc
  s   
zterminate.<locals>.term_psprocc                    sB   zt | }W n t jy   trt| | Y S Y d S w  ||S r   )r   r   r   r
   r   )r   r   r   )r  ry   rz   term_pid  s   
zterminate.<locals>.term_pidc                 S   s8   | j r| j   | jr| j  | jr| j  d S d S r   )rr   r   rs   r   )r   ry   ry   rz   flush_popen  s   

zterminate.<locals>.flush_popenzwrong type %r)	r   r   rt   r   r   r   
pid_existsr   	TypeError)Zproc_or_pidr  wait_timeoutr
  r  r  r   r   ry   )r  r  r  r   rz   r;     s>   



	



r;   c                 C   s   t  j| d}trt }t| ts
tr t }t| ts|rH|D ]}t|dd q$t j|td\}}|D ]}t	d|  t|t
jd q8dS dS )a  Terminate and wait() any subprocess started by this test suite
    and any children currently running, ensuring that no processes stick
    around to hog resources.
    If resursive is True it also tries to terminate and wait()
    all grandchildren started by this process.
    	recursiveN)r  r   z0couldn't terminate process %r; attempting kill())r  )r   r   childrenr   popr;   r   
wait_procsr    rZ   r   r   )r  r  r   r   r   ZgoneZalivery   ry   rz   r<   5  s$   
r<   c                  C   s   t stdd} t d }|D ]}| s|dkr| |7 } q | s(td| d}d}| d}t|d }t|dkrCt|d }t|dkrOt|d }|||fS )	z"Return a tuple such as (2, 6, 36).z	not POSIX r~   .zcan't parse %rr      r   )	r
   NotImplementedErrorr   unameisdigitr   splitr   len)r   r  cminormicroZnumsmajorry   ry   rz   rM   Z  s&   


rM   c                  C   sd   t stdt } t| dr| jpd}ntd| d }|r't|	d}nd}| d | d |fS )Nznot WINDOWSservice_pack_majorr   z\s\d$r   r  )
r   r  r   Zgetwindowsversionhasattrr"  researchr   group)Zwvsprry   ry   rz   rL   r  s   
rL   c                   @   s<   e Zd ZdZeddddfddZdd Zdd	 Zd
d ZdS )retryzA retry decorator.Nr   c                 C   s2   |r|rt d|| _|| _|| _|| _|| _d S )Nz/timeout and retries args are mutually exclusive)r   	exceptionr   retriesintervallogfun)r   r*  r   r+  r,  r-  ry   ry   rz   r     s   
zretry.__init__c                 c   sf    | j rt | j  }t |k rd V  t |k sd S d S | jr.t| jD ]}d V  q&d S 	 d V  q/r   )r   r   r+  r   )r   stop_atr   ry   ry   rz   __iter__  s   zretry.__iter__c                 C   s   | j d urt| j  d S d S r   )r,  r   r   r   ry   ry   rz   r     s   
zretry.sleepc                    s"   t   fdd}|_|S )Nc                     sr   d }D ]/}z
 | i |W   S  j y3 } z|}jd ur%|   W Y d }~qd }~ww tr8| r   )r*  r-  r   r   )r   r   excr   r   r   ry   rz   r     s   

zretry.__call__.<locals>.wrapper)r   r   	decorator)r   r   r   ry   r1  rz   __call__  s   zretry.__call__)	r   r   r   r   rw   r   r/  r   r3  ry   ry   ry   rz   r)    s    
r)  r   )r*  r-  r   r,  c                 C   s    t |  trtd dS dS )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.
    {Gz?N)r   r   r   r   r   )r   ry   ry   rz   rO     s   
rO   Tc                 C   sN   t | d}| }W d   n1 sw   Y  |s|sJ |r%t|  |S )z8Wait for a file to be written on disk with some content.rbN)r   readrI   )fnamer   r   r   datary   ry   rz   rP     s   
rP   c                 C   s   |  }t |s	J |S )zVKeep calling function for timeout secs and exit if eval()
    expression is True.
    )eval)r   exprretry   ry   rz   rN     s   rN   c                 C   sp   dd }z)t | }t|jrttj| }ntt j| }t	r'|  W dS || W dS  t
y7   Y dS w )z>Convenience function for removing temporary test files or dirsc              
   S   s   t   t }t   |k r@z|  W S  ty   Y n ty4 } z|}tdt|  W Y d }~nd }~ww t d t   |k s|)Nzignoring %sr4  )r   r    r   ZWindowsErrorrZ   r   r   )r   r.  r   r  ry   ry   rz   	retry_fun  s   
	zsafe_rmpath.<locals>.retry_funN)r   statS_ISDIRst_moder   partialshutilrmtreeremover
   r   )r   r<  str   ry   ry   rz   rI     s   
rI   c                 C   s&   zt |  W dS  ty   Y dS w )z-Convenience function for creating a directoryN)r   mkdirr   r   ry   ry   rz   
safe_mkdir
  s
   rF  c              	   c   s8    t  }zt |  dV  W t | dS t | w )z@Context manager which temporarily changes the current directory.N)r   r   rH   )dirnamecurdirry   ry   rz   rH     s   
rH   c                 C   s   t j| r
J | |r]tdstdt|trtd}t|t	s'J |t
tddd}|| W d   n1 s?w   Y  ztd|jd| g W t|j dS t|j w tt|  trvt | }t | |jtjB  dS dS )	z1Creates an executable file in the given location.gcczgcc is not installedz
                #include <unistd.h>
                int main() {
                    pause();
                    return 1;
                }
                z.csuffixr   Nz-o)r   r   r   r   r   r   boolr   r   r   r   rK   r   rt   ru   r   rI   rA  copyfiler$   r
   r=  chmodr?  S_IEXEC)ZoutpathZc_coder   rD  ry   ry   rz   rJ     s(   

rJ   r  c                 C   s,   	 t jt| |d}tj|stj|S q)zReturn an absolute pathname of a file or dir that did not
    exist at the time this call is made. Also schedule it for safe
    deletion at interpreter exit. It's technically racy but probably
    not really due to the time variant.
    T)prefixrK  r   )tempfileZmktempr'   r   r   r   r   )rK  r   r   ry   ry   rz   rK   ;  s
   rK   c                   @   s8   e Zd Zdd ZeejdsejjZe	sdd Z
dS dS )TestCasec                 C   s.   | j j}|dsd| }d|| j j| jf S )Nzpsutil.zpsutil.tests.z%s.%s.%s)r   r   r   r   Z_testMethodName)r   Zfqmodry   ry   rz   __str__P  s   
zTestCase.__str__assertRaisesRegexc                 C   s   d S r   ry   r   ry   ry   rz   runTest^  s   zTestCase.runTestN)r   r   r   rS  r#  unittestrR  ZassertRaisesRegexprT  r   rU  ry   ry   ry   rz   rR  L  s    	rR  c                   @   sB   e Zd ZdZdddZdd Zdd	 Zd
d Zdd Zdd Z	dS )rD   zUTest class providing auto-cleanup wrappers on top of process
    test utilities.
    r  Nc                 C   s   t ||d}| t| |S )N)rK  r   )rK   
addCleanuprI   )r   rK  r   r7  ry   ry   rz   rK   k  s   zPsutilTestCase.get_testfnc                 O   s   t |i |}| t| |S r   )r=   rW  r;   )r   r   r   r   ry   ry   rz   r=   p  s   zPsutilTestCase.spawn_testprocc                 C   *   t  \}}| t| | t| ||fS r   )r?   rW  r;   )r   Zchild1Zchild2ry   ry   rz   r?   u     
z"PsutilTestCase.spawn_children_pairc                 C   rX  r   )r>   rW  r;   )r   r   r   ry   ry   rz   r>   {  rY  zPsutilTestCase.spawn_zombiec                 O   s.   t |i |\}}| t| | t| |S r   )r:   rW  rI   r;   )r   r   r   r   r   ry   ry   rz   r:     s   zPsutilTestCase.pyrunc                 C   s   |  tjtj|j t|tjtjfr6| rJ z| }W n
 tjy)   Y nw t	d| |j
dd t|jrAJ |j| |jt  d S )Nz3Process.status() didn't raise exception (status=%s)r   r   )assertRaisesr   r   r   r   r   r   
is_runningr   AssertionErrorr   r  ZassertNotInpids)r   r   r   ry   ry   rz   assertProcessGone  s   z PsutilTestCase.assertProcessGoner  N)
r   r   r   r   rK   r=   r?   r>   r:   r^  ry   ry   ry   rz   rD   f  s    
rD   zunreliable on PYPYc                   @   s   e Zd ZdZdZdZdZerdndZdZ	e
 ZeeddZedd	 Zed
d Zdd Zdd Zdd Zdd Zdd Zdd Zdd Z		dddZdd ZdS ) rC   a  Test framework class for detecting function memory leaks,
    typically functions implemented in C which forgot to free() memory
    from the heap. It does so by checking whether the process memory
    usage increased before and after calling the function many times.

    Note that this is hard (probably impossible) to do reliably, due
    to how the OS handles memory, the GC and so on (memory can even
    decrease!). In order to avoid false positives, in case of failure
    (mem > 0) we retry the test for up to 5 times, increasing call
    repetitions each time. If the memory keeps increasing then it's a
    failure.

    If available (Linux, OSX, Windows), USS memory is used for comparison,
    since it's supposed to be more precise, see:
    https://gmpy.dev/blog/2016/real-process-memory-and-environ-in-python
    If not, RSS memory is used. mallinfo() on Linux and _heapwalk() on
    Windows may give even more precision, but at the moment are not
    implemented.

    PyPy appears to be completely unstable for this framework, probably
    because of its JIT, so tests on PYPY are skipped.

    Usage:

        class TestLeaks(psutil.tests.TestMemoryLeak):

            def test_fun(self):
                self.execute(some_function)
       r^   r   r_   TZPSUTIL_DEBUGc                 C   s   t d d S )NF)r   
_set_debugclsry   ry   rz   
setUpClass     zTestMemoryLeak.setUpClassc                 C   s   t | j d S r   )r   ra  _psutil_debug_origrb  ry   ry   rz   tearDownClass     zTestMemoryLeak.tearDownClassc                 C   s   | j  }t|d|jS )NZuss)	_thisprocmemory_full_infor   Zrss)r   memry   ry   rz   _get_mem  s   
zTestMemoryLeak._get_memc                 C   s   t r| j S | j S r   )r
   ri  num_fdsnum_handlesr   ry   ry   rz   _get_num_fds  s   

zTestMemoryLeak._get_num_fdsc                 C   s   | j rt|dtjd d S d S )NZyellow)Zcolorfile)verboser   r   rs   )r   msgry   ry   rz   _log  s   zTestMemoryLeak._logc                 C   sx   |   }| | |   }|| }|dk r| d| |dkr:tr$dnd}|dkr.|d7 }d|||f }| |dS )	zMakes sure num_fds() (POSIX) or num_handles() (Windows) does
        not increase after calling a function.  Used to discover forgotten
        close(2) and CloseHandle syscalls.
        r   zHnegative diff %r (gc probably collected a resource from a previous test)fdZhandler  r   z%s unclosed %s after calling %rN)ro  callfailr
   )r   r   ZbeforeZafterdiffZtype_rr  ry   ry   rz   
_check_fds  s   

zTestMemoryLeak._check_fdsc                 C   s^   t jdd |  }t|D ]	}| |}~~qt jdd |  }| t jg  || }|S )zGet 2 distinct memory samples, before and after having
        called fun repeadetly, and return the memory difference.
        r  )Z
generation)gcZcollectrl  r   ru  ZassertEqualZgarbage)r   r   timesZmem1r   r;  Zmem2rw  ry   ry   rz   _call_ntimes  s   
zTestMemoryLeak._call_ntimesc                 C   s   g }d}|}t d|d D ]C}	| ||}
d|	t|
t|
| |f }|| |
|kp/|
|k}|r>|	dkr;| |  d S |	dkrEt  | | ||7 }|
}q| d|)Nr   r  z,Run #%s: extra-mem=%s, per-call=%s, calls=%sz. )r   r{  r   appendrs  printrv  r   )r   r   rz  warmup_timesr+  	tolerancemessagesZprev_memZincreaseidxrk  rr  Zsuccessry   ry   rz   
_check_mem  s(   


zTestMemoryLeak._check_memc                 C   s   | S r   ry   )r   r   ry   ry   rz   ru    s   zTestMemoryLeak.callNc              
   C   s   |dur|n| j }|dur|n| j}|dur|n| j}|dur!|n| j}z"|dks-J d|dks5J d|dks=J d|dksEJ dW n tyX } ztt|d}~ww | || | | | j	|||||d dS )	zTest a callable.Nr  ztimes must be >= 1r   zwarmup_times must be >= 0zretries must be >= 0ztolerance must be >= 0)rz  r~  r+  r  )
rz  r~  r+  r  r\  r   r   r{  rx  r  )r   r   rz  r~  r+  r  r  ry   ry   rz   execute  s(   


zTestMemoryLeak.executec                    s&    fdd}j |fi | dS )znConvenience method to test a callable while making sure it
        raises an exception on every call.
        c                      s      d S r   )rZ  ry   r0  r   r   ry   rz   ru  -  s   z*TestMemoryLeak.execute_w_exc.<locals>.callN)r  )r   r0  r   r   ru  ry   r  rz   execute_w_exc)  s   zTestMemoryLeak.execute_w_exc)NNNN)r   r   r   r   rz  r~  r  r*   r+  rq  r   r   ri  rL  r   getenvrf  classmethodrd  rg  rl  ro  rs  rx  r{  r  ru  r  r  ry   ry   ry   rz   rC     s0    


rC   c                  C   s  dd l } dd l}dd l}dd l}dd l}dd l}zdd l}W n ty)   d }Y nw zdd l}W n ty;   d }Y nw | 	 }t
jrNtdrNtd|d< n=t
jr\d| d  |d< n/t
jrddtt|  |d< t|dr~|d  d	|  7  < nd
| | f |d< d	t| | g |d< t
jr| d |d< d	| | |  g|d< t!|dd|d< |d ur|d  d|j" 7  < t
jrtdrtddg}	t|	#dd |d< nd|d< |$ d }
|
r|
|d< t%& |d< |' }d|d |d f |d< |j(t
) *d|d< |j+ *d|d< |, |d< t-j./d|d < t-0 |d!< t1|d"< |2 |d#< t-3 |d$< t
4 |d%< d&t5d'd( t
6 D  |d)< t
7 }d*t8|j9t:|j;t:|j<f |d+< t
= }d*t8|j9t:|j;t:|j<f |d,< t>t
? |d-< t
@ A }|Bd.d  |C||d/< tDd0t%jEd1 |F D ]\}}tDd2|d3 |f t%jEd1 qtDd0t%jEd1 t%jGH  d S )4Nr   Zlsb_releasezlsb_release -d -sZOSz	Darwin %szWindows  win32_editionz, z%s %sZarchr~   Zkernelr}   __version__znot installedpipz (wheel=%s)rI  z	--versionr   r  Zglibczfs-encodingz%s, %slangz%Y-%m-%d %H:%M:%Sz	boot-timer   user~homer   ZpyexeZhostnameZPIDZcpusz%.1f%%, %.1f%%, %.1f%%c                 S   s   g | ]
}|t   d  qS )d   )r   	cpu_countr   ry   ry   rz   r   {      z!print_sysinfo.<locals>.<listcomp>Zloadavgz%s%%, used=%s, total=%sZmemoryswapr]  ri   r   zF======================================================================rp  z%-17s %s:)Icollectionsdatetimegetpasslocaleplatformpprintr  ImportErrorwheelOrderedDictr   r   r   r   ZOSXZmac_verr   r   mapr   Z	win32_verr#  r  systemversionlistZarchitecturemachiner
   r  Zpython_implementationZpython_versionZpython_compilerr   r  r  Zlibc_verr   getfilesystemencoding	getlocaleZfromtimestamp	boot_timestrftimeZnowZgetuserr   r   
expanduserr   r$   Znodegetpidr  tuplerf   virtual_memoryr   percentr   usedtotalswap_memoryr  r]  r   as_dictr  Zpformatr}  rs   itemsrr   flush)r  r  r  r  r  r  r  r  infooutr   r  rk  r  Zpinfokvry   ry   rz   rG   3  s   




rG   c                  C   s6   t  } t| dr|  S t| drt|  S dS )Nrk   rd   r   )r   r   r#  rk   randomchoicerd   )r   ry   ry   rz   _get_eligible_cpu  s   

r  c                   @   s0  e Zd ZdZddi fddi fgZddi fddddifd	di fd
di fddi fddi fddi fddi fddi fg	Zddi fddddifddi fddi fddi fddi fddi fddi fddi fddi fddi fddi fddi fd di fd!di fd"di fd#di fgZered$di fg7 Zed%di fg7 Zed&di fg7 Zed'di fg7 Zered(di fg7 Ze	red)di fg7 Ze
red*ejfi fg7 Zered+di fg7 Zered,di fg7 Zered-di fg7 Zered.di fg7 Zered/dd0d1ifg7 Zg Zereddi fg7 Zn
edejfi fg7 Ze
red*ejd2fi fg7 Ze	r8er.ed)ejd3fi fg7 Zn
ed)ejfi fg7 ZerFed+e gfi fg7 Zd4ejfi fd5di fd6di fd7di fd8di fgZerued4ejfi fg7 Zed4ejfi fg7 Zee e e Zd9d: ZdDd;d<Zd=d> Z e!d?d@ Z"e!dAdB Z#dCS )ErE   a  A container that lists all Process class method names + some
    reasonable parameters to be called with. Utility methods (parent(),
    children(), ...) are excluded.

    >>> ns = process_namespace(psutil.Process())
    >>> for fun, name in ns.iter(ns.getters):
    ...    fun()
    cpu_percentry   Zmemory_percentr  r  r  Tr[  Zmemory_info_exZoneshotr   parentsr   r   r   ZcmdlineZconnectionskindall	cpu_timesZcreate_timer   rx   rj  Zmemory_infor   niceZnum_ctx_switchesZnum_threadsZ
open_filesZppidr   rq   ZusernameZuidsZgidsZterminalrm  rl   rh   rm   rd   rk   rg   rn  ri   ZgroupedF)r   i   r   r   ZsuspendZresumer;   killc                 C   s
   || _ d S r   )_proc)r   r   ry   ry   rz   r     s   
zprocess_namespace.__init__c                 c   sb    t |}t| |D ]"\}}}|r|   t| j|}tj|g|R i |}||fV  qdS z_Given a list of tuples yields a set of (fun, fun_name) tuples
        in random order.
        N)r  r  shuffleclear_cacher   r  r   r@  )r   lsr  fun_namer   r   r   ry   ry   rz   iter  s   
zprocess_namespace.iterc                 C   s   | j j| j jdd dS )z&Clear the cache of a Process instance.T)Z_ignore_nspN)r  Z_initr   r   ry   ry   rz   r    s   zprocess_namespace.clear_cachec                 C   s>   |D ]\}}}d| }t ||sd|jj|f }t|qdS )z}Given a TestCase instance and a list of tuples checks that
        the class defines the required test method names.
        Ztest_z$%r class should define a '%s' methodN)r#  r   r   AttributeError)rc  Z
test_classr  r  r   Z	meth_namerr  ry   ry   rz   test_class_coverage
  s   
z%process_namespace.test_class_coveragec                 C   s`   t dd | jD }t dd | jD }t dd ttjD }||B |A }|r.td| d S )Nc                 S      g | ]}|d  qS r  ry   r   ry   ry   rz   r         z*process_namespace.test.<locals>.<listcomp>c                 S   r  r  ry   r   ry   ry   rz   r     r  c                 S   s   g | ]
}|d  dkr|qS )r   r   ry   r   ry   ry   rz   r     r  z!uncovered Process class names: %r)r   r  ignoredr   r   r   r   )rc  thisr  klassZleftoutry   ry   rz   test  s   zprocess_namespace.testN)T)$r   r   r   r   Zutilsr  gettersr
   r1   r2   r5   r   ZRLIMIT_NOFILEr.   r4   r0   r   r3   ZsettersZNORMAL_PRIORITY_CLASSr   ZIOPRIO_CLASS_NONEZIOPRIO_NORMALr  r   SIGTERMZkillersZCTRL_C_EVENTZCTRL_BREAK_EVENTr  r   r  r  r  r  r  ry   ry   ry   rz   rE     s    	

rE   c                   @   s  e Zd ZdZddi fddddifddddifddi fd	dd
difd	dd
difddddifddddifde fi fddddifddi fddi fddddifde fi fddi fddi fddi fddi fgZerreddd
difg7 Ze	r|eddi fg7 Ze
reddi fg7 Zereddi fg7 Zereddi fg7 Zered di fg7 Zed!d"i fg7 Zd#di fd$e gfi fd%di fd&di fgZeZed'd( ZejZd)S )*rF   zA container that lists all the module-level, system-related APIs.
    Utilities such as cpu_percent() are excluded. Usage:

    >>> ns = system_namespace
    >>> for fun, name in ns.iter(ns.getters):
    ...    fun()
    r  ry   r  ZlogicalFTZ	cpu_statsr  ZpercpuZdisk_io_countersZperdiskZdisk_partitionsr  
disk_usageZnet_connectionsr  Znet_if_addrsZnet_if_statsrj   Zpernicr  r]  r  Zusersr  re   rf   rp   ro   rn   Zwin_service_iterZwin_service_get)ZalgZprocess_iterr  r  Zcpu_times_percentc                 c   sT    t | } t|  | D ]\}}}tt|}tj|g|R i |}||fV  qdS r  )r  r  r  r   r   r   r@  )r  r  r   r   r   ry   ry   rz   r  S  s   

zsystem_namespace.iterN)r   r   r   r   r   r   r  r  r/   HAS_GETLOADAVGr9   r8   r6   r   r   r   r  r  staticmethodr  rE   r  ry   ry   ry   rz   rF      sV    

rF   c                 C   s   t | s	J | d| _| S )zA decorator to mark a TestCase class. When running parallel tests,
    class' unit tests will be run serially (1 process).
    T)inspectZisclassZ
_serialrun)r  ry   ry   rz   	serialrunb  s   r  c                 C   s   dd }t td| |dS )zZDecorator which runs a test function and retries N times before
    actually failing.
    c                 S   s   t d|  tjd d S )Nz%r, retryingr  )r}  r   rs   )r0  ry   ry   rz   r-  p  s   z retry_on_failure.<locals>.logfunN)r*  r   r+  r-  )r)  r\  )r+  r-  ry   ry   rz   rB   l  s   rB   c                        fdd}|S )z,Decorator to Ignore AccessDenied exceptions.c                       t   fdd}|S )Nc                     s:   z | i |W S  t jy   d urs tdw )Nzraises AccessDenied)r   ZAccessDeniedrV  SkipTestr   r   only_ifry   rz   r   z  s   
z9skip_on_access_denied.<locals>.decorator.<locals>.wrapperr   r   r  r   rz   r2  y  s   z(skip_on_access_denied.<locals>.decoratorry   r  r2  ry   r  rz   r@   w  s   r@   c                    r  )z3Decorator to Ignore NotImplementedError exceptions.c                    r  )Nc                     sB   z | i |W S  t y    d urs d j }t|w )Nz4%r was skipped because it raised NotImplementedError)r  r   rV  r  )r   r   rr  r  ry   rz   r     s   
z;skip_on_not_implemented.<locals>.decorator.<locals>.wrapperr   r   r  r   rz   r2    s   
z*skip_on_not_implemented.<locals>.decoratorry   r  ry   r  rz   rA     s   rA   	127.0.0.1c                 C   sL   t t }|| df | d W  d   S 1 sw   Y  dS )z6Return an unused TCP port. Subject to race conditions.r   r  N)
contextlibclosingsocketbindgetsockname)Zhostr   ry   ry   rz   rR     s   
$rR   c                 C   s~   |du r| t tfv rd}t| |}z tjdvr!|tjtjd || |tj	kr0|
d |W S  ty>   |   w )zBinds a generic socket.Nr  r   )ntcygwinr  r_   )r   r   r  r   r   Z
setsockoptZ
SOL_SOCKETZSO_REUSEADDRr  r   listenrw   r   )familytypeaddrr   ry   ry   rz   rS     s   



rS   c                 C   sp   t jsJ tj| rJ | ttj|}z||  |tjkr)|	d W |S W |S  t
y7   |   w )zBind a UNIX socket.r_   )r   r
   r   r   r   r  r   r  r   r  rw   r   )r   r  r   ry   ry   rz   rT     s   


rT   r  c              	   C   s   t t| tG}|| |d | }t| t}z%|| | }	 | \}}||kr?||fW W  d   S |	  q) t
yO   |	   w 1 sSw   Y  dS )z^Build a pair of TCP sockets connected to each other.
    Return a (server, client) tuple.
    r_   TN)r  r  r  r   r  r  r  connectr   r   r  )r  r  Zllr  Zcaddrary   ry   rz   rU     s(   


rU   c                 C   s   t jsJ d }}z#t| tjd}|d ttjtj}|d ||  W ||fS  tyD   |dur;|	  |durC|	   w )zBuild a pair of UNIX sockets connected to each other through
    the same UNIX file name.
    Return a (server, client) tuple.
    Nr  r   )
r   r
   rT   r  r   Zsetblockingr   r  rw   r   )r   ZserverZclientry   ry   rz   rV     s    


rV   c               	   c   s   g } d }}zm|  ttjtj |  ttjtj t r3|  ttjtj |  ttjtj trWt	rWt
 }t
 }t|\}}t|tjd}|||fD ]}|  | qO| V  W | D ]}|  q]||fD ]
}|durrt| qhdS | D ]}|  qw||fD ]
}|durt| qw )z1Open as many socket families / types as possible.Nr  )r|  rS   r  r   r   
SOCK_DGRAMr   r   r
   HAS_CONNECTIONS_UNIXrK   rV   rT   r   rI   )ZsocksZfname1Zfname2s1s2Zs3r   r7  ry   ry   rz   rW     s>   

rW   c                 C   s  ddl }trtrtst|tjsJ ||tjkrQdd | dD }t	|dks-J | |D ]}d|  kr>dksCJ |  J | q/tsJt
| } ||  dS |tjkrlt| ts_J | tset
| } ||  dS |tjkrtd| dus}J | dS td	|)
z[Check a net address validity. Supported families are IPv4,
    IPv6 and MAC addresses.
    r   Nc                 S   s   g | ]}t |qS ry   )r   r   ry   ry   rz   r     r  z%check_net_address.<locals>.<listcomp>r  r      z([a-fA-F0-9]{2}[:|\-]?){6}zunknown family %r)	ipaddressenumr   r#   r   IntEnumr  r   r  r  r   ZIPv4Addressr   r   ZIPv6Addressr   ZAF_LINKr$  matchr   )r  r  r  ZoctsZnumry   ry   rz   rQ     s&   
&


rQ   c                 C   sT   dd }dd }dd }dd }d	d
 }||  ||  ||  ||  ||  dS )z*Check validity of a connection namedtuple.c                 S   s   t | dk}t | dv sJ t | | d | jksJ | j| d | jks*J | j| d | jks6J | j| d | jksBJ | j| d | jksNJ | j| d | jksZJ | j|rh| d	 | jksjJ | jd S d S )
N   )r  r  r   r  r~   r   r   r_   r  )r  rt  r  r  laddrraddrr   r   )r   Zhas_pidry   ry   rz   check_ntuple+  s   z-check_connection_ntuple.<locals>.check_ntuplec                 S   s  | j tttfv sJ | j td urt| j tjsJ | n
t| j ts'J | | j tkr{t| j | j	}t
|8 z|| jd df W n tjy` } z|jtjkrV W Y d }~nd }~ww W d    d S W d    d S 1 stw   Y  d S | j tkr| jtjksJ | jd S d S )Nr   )r  r   r   r   r  r   r  r   r  r  r  r  r  r  errorr  ZEADDRNOTAVAILr   r   	CONN_NONE)r   r   r  ry   ry   rz   check_family7  s.   
"
z-check_connection_ntuple.<locals>.check_familyc                 S   s   t tdt }| jtjtj|fv sJ | jtd ur&t| jtjs%J | n
t| jt	s0J | | jtjkrA| j
tjksCJ | j
d S d S )NSOCK_SEQPACKET)r   r  objectr  r   r  r  r   r  r   r   r   r  )r   r  ry   ry   rz   
check_typeL  s   z+check_connection_ntuple.<locals>.check_typec                 S   s   | j | jfD ]M}| jttfv rCt|tsJ t||sqt|jt	s*J t|jd|j  kr5dks;n J |jt
|j| j q| jtkrSt|tsSJ t|qd S )Nr   i  )r  r  r  r   r   r   r  r  Zportr   rQ   Zipr   r   )r   r  ry   ry   rz   check_addrsX  s   "
z,check_connection_ntuple.<locals>.check_addrsc                 S   s   t | jtsJ | jdd ttD }| j|v sJ | j| jttfv r7| jt	kr7| jtj
ks5J | jd S | jtj
ksBJ | jd S )Nc                 S   r   )ZCONN_r   r   ry   ry   rz   r   g  r   zAcheck_connection_ntuple.<locals>.check_status.<locals>.<listcomp>)r   r   r   r   r   r  r   r   r  r   r  )r   Zvalidsry   ry   rz   check_statuse  s   z-check_connection_ntuple.<locals>.check_statusNry   )r   r  r  r  r  r  ry   ry   rz   check_connection_ntuple)  s   
r  c                 C   sJ   zddl }t|dstW n ty   ddl}||  Y S w || S )z,Backport of importlib.reload of Python 3.3+.r   Nreload)	importlibr#  r  impr  )moduler  r  ry   ry   rz   rX   {  s   

rX   c                 C   s   t jt j| d }tjd dkrdd l}||| S tjd d dkr3ddlm	} ||| 
 S dd l}|j|| }|j|}|j| |S )Nr   r~   r   )SourceFileLoader)r   r   splitextr   r   r   r  Zload_sourceimportlib.machineryr	  load_moduleimportlib.utilutilspec_from_file_locationmodule_from_specloaderexec_module)r   r   r  r	  r  specmodry   ry   rz   rY     s   rY   c                 C   s   t | t dS )zRaise a warning msg.N)warningsrZ   UserWarning)rr  ry   ry   rz   rZ     rh  rZ   c                 C   sV   t | }|j}t|dks|d tkrdS t|dd}t|ts"dS tdd |D S )z-Check if object is an instance of namedtuple.r  r   F_fieldsNc                 s   s    | ]	}t |tkV  qd S r   )r  r   )r   nry   ry   rz   	<genexpr>  s    z is_namedtuple.<locals>.<genexpr>)r  	__bases__r  r  r   r   r  )r   tbr   ry   ry   rz   r\     s   
r\   c                 #   s|    t rdnd dt|  d} fddt  D }t|}t|| zt	
| |V  W t| dS t| w )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.
        r|   r}   z.sorJ  c                    s6   g | ]}t j|jd  kr |j v r|jqS )r  )r   r   r
  lowerr   rx   extry   rz   r     s
    'copyload_shared_lib.<locals>.<listcomp>N)r#   rK   r   r   ri   r  r  rA  rM  ctypesZCDLLrI   )rK  dstlibsr   ry   r  rz   r[     s   

r[   c           	      #   s   ddl m} ddl m} d t|   d} fddt  D }tr2|s2dd t  D }t	|}t
|| d	}z)t |}|V  W |d	urct jjj}|jg|_||j}|dkrc|  t| d	S |d	urt jjj}|jg|_||j}|dkr|  t| w )
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   )WinError)wintypesz.dllrJ  c                    sF   g | ]}|j   rd tj |j  v rd|j  vr|j qS )r}   Zwow64)r   r  r   r   r   r   r  ry   rz   r     s    r   c                 S   s(   g | ]}d t j|j v r|jqS )r|   )r   r   r   r  r   ry   ry   rz   r     s    N)r!  r$  r%  rK   r   r   ri   r#   r  r  rA  rM  ZWinDLLZwindllZkernel32FreeLibraryZHMODULEargtypesZ_handlerI   )	rK  r$  r%  r"  r#  r   cfiler'  r;  ry   r&  rz   r[     s8   








c                   C   s   t dd d S )NTr  )r<   ry   ry   ry   rz   cleanup_test_procs  re  r*  c                 C   s
   t | S r   )r   exit)r  framery   ry   rz   r     s   
 r   r   )F)TFr_  )r  )r  )r  )r   Z
__future__r   atexitr  r!  r  r   ry  r  r   r  r$  r   rA  r   r  r=  rt   r   rQ  r   r   r   r  r   r   r   r   r   r   r   r	   r
   r   r   Zpsutil._commonr   r   r   Zpsutil._compatr   r   r   r   r   r   r   r   rV  Z	unittest2r   r  catch_warningssimplefilterr   r  Zpsutil._psposixr   __all__builtin_module_namesr#   rg   r   r]   r*   maxsizer-   r"   r!   r,   r    r   r  r'   r(   decoder)   r  r  ZASCII_FSr   r   r   rG  __file__r%   r&   ZHEREr  r#  r   r.   r/   r  r0   r2   r3   ZHAS_NET_IO_COUNTERSr4   r1   r5   r6   rL  rn   r7   rw   r8   r9   ZHAS_THREADSgetuidZSKIP_SYSCONSr   r$   r   devnullr   registerr   r   r+   r   r   r   r   r   r   r   r   r   r=   r?   r>   r:   r   r  r;   r<   rM   rL   r)  r   rO   r\  rP   rN   rI   rF  contextmanagerrH   rJ   rK   rR  rD   ZskipIfrC   rG   r  rE   rF   r  rB   r@   rA   rR   rS   rT   rU   rV   rW   rQ   r  rX   rY   rZ   r\   r[   r*  ry   ry   ry   rz   <module>   s  





-








 0'
&-


U%
:



!




1 [	 
B





R,
