B
    çÚ†\;3  ã            	   @   sÆ  d 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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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Zd"d#„ Zd$d%„ Z(erÆe# )d&¡d'  *d&d(¡Z+ne#d) Z+G d*d+„ d+e,ƒZ-e& .eoêe%d,¡e& .eoúe%d-¡e& .ed.¡e& .e(e$ƒ d/¡G d0d1„ d1e-e&j/ƒƒƒƒƒZ0e& .eo@e%d,¡e& .eoPe%d-¡e& .e(e+ƒ d2¡G d3d4„ d4e-e&j/ƒƒƒƒZ1e& .e d5¡G d6d7„ d7e&j/ƒƒZ2G d8d9„ d9e&j/ƒZ3e4d:krÂee5ƒ dS );aó  
Notes about unicode handling in psutil
======================================

In psutil these are the APIs returning or dealing with a string
('not tested' means they are not tested to deal with non-ASCII strings):

* Process.cmdline()
* Process.connections('unix')
* Process.cwd()
* Process.environ()
* Process.exe()
* Process.memory_maps()
* Process.name()
* Process.open_files()
* Process.username()             (not tested)

* disk_io_counters()             (not tested)
* disk_partitions()              (not tested)
* disk_usage(str)
* net_connections('unix')
* net_if_addrs()                 (not tested)
* net_if_stats()                 (not tested)
* net_io_counters()              (not tested)
* sensors_fans()                 (not tested)
* sensors_temperatures()         (not tested)
* users()                        (not tested)

* WindowsService.binpath()       (not tested)
* WindowsService.description()   (not tested)
* WindowsService.display_name()  (not tested)
* WindowsService.name()          (not tested)
* WindowsService.status()        (not tested)
* WindowsService.username()      (not tested)

In here we create a unicode path with a funky non-ASCII name and (where
possible) make psutil return it back (e.g. on name(), exe(), open_files(),
etc.) and make sure that:

* psutil never crashes with UnicodeDecodeError
* the returned path matches

For a detailed explanation of how psutil handles unicode see:
- https://github.com/giampaolo/psutil/issues/1040
- http://psutil.readthedocs.io/#unicode
é    N)Úclosing)ÚBSD)ÚMACOS)ÚOPENBSD)ÚPOSIX)ÚWINDOWS)ÚPY3)Úu)ÚAPPVEYOR)ÚASCII_FS)Úbind_unix_socket)Úchdir)Úcopyload_shared_lib)Ú
create_exe)Úget_test_subprocess)ÚHAS_CONNECTIONS_UNIX)ÚHAS_ENVIRON)ÚHAS_MEMORY_MAPS)Úmock)ÚPYPY)Úreap_children)Úrun_test_module_by_name)Ú
safe_mkdir)Úsafe_rmpath)Úskip_on_access_denied)ÚTESTFILE_PREFIX)ÚTESTFN)ÚTESTFN_UNICODE)ÚTRAVIS)Úunittest)Úunix_socket_pathc             C   s8   t r,yt| ƒS  tk
r(   t ¡  Y q4X nt| ƒS d S )N)r
   Ú_safe_rmpathZWindowsErrorÚ	tracebackÚ	print_exc)Úpath© r%   ú8lib/python3.7/site-packages/psutil/tests/test_unicode.pyr   ]   s    r   c             C   sT   t rdS z>y t| ƒ t| ƒ t| gd W n tk
r>   dS X dS W dtƒ  X dS )z`Return True if both the fs and the subprocess module can
    deal with a unicode file name.
    T)ÚcmdFN)r   r   r   r   ÚUnicodeEncodeErrorr   )Únamer%   r%   r&   Úsubprocess_supports_unicodeq   s    r*   Úutf8s   fÀ€Úsurrogateescapeu   fÃ€Â€c               @   sÌ   e Zd Z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e e d¡dd„ ƒZe e d¡e e d¡eƒ dd„ ƒƒƒZdd„ Ze e d¡e e d¡dd„ ƒƒZdS ) Ú_BaseFSAPIsTestsNc             C   s   t | jƒ t| jƒ d S )N)r   Ú
funky_namer   )Úclsr%   r%   r&   Ú
setUpClass“   s    
z_BaseFSAPIsTests.setUpClassc             C   s   t ƒ  t| jƒ d S )N)r   r   r.   )r/   r%   r%   r&   ÚtearDownClass˜   s    z_BaseFSAPIsTests.tearDownClassc             C   s
   t ƒ  d S )N)r   )Úselfr%   r%   r&   ÚtearDown   s    z_BaseFSAPIsTests.tearDownc             C   s   t dƒ‚d S )Nzmust be implemented in subclass)ÚNotImplementedError)r2   r%   r%   r&   Úexpect_exact_path_match    s    z(_BaseFSAPIsTests.expect_exact_path_matchc             C   sH   t | jgd}t |j¡}| ¡ }|  |t¡ |  ¡ rD|  	|| j¡ d S )N)r'   )
r   r.   ÚpsutilÚProcessÚpidÚexeÚassertIsInstanceÚstrr5   ÚassertEqual)r2   ÚsubpÚpr9   r%   r%   r&   Útest_proc_exe£   s    z_BaseFSAPIsTests.test_proc_exec          	   C   s   t | jgd}trRtjdt t ¡ ¡d }t 	|j
¡ ¡ }|jsFt‚W d Q R X nt 	|j
¡ ¡ }|  |t¡ |  ¡ rŒ|  |tj | j¡¡ d S )N)r'   z psutil._psplatform.cext.proc_exe)Úside_effect)r   r.   r   r   Úpatchr6   ÚAccessDeniedÚosÚgetpidr7   r8   r)   ÚcalledÚAssertionErrorr:   r;   r5   r<   r$   Úbasename)r2   r=   Úmr)   r%   r%   r&   Útest_proc_name«   s    z_BaseFSAPIsTests.test_proc_namec             C   sX   t | jgd}t |j¡}| ¡ }x|D ]}|  |t¡ q(W |  ¡ rT|  	|| jg¡ d S )N)r'   )
r   r.   r6   r7   r8   Úcmdliner:   r;   r5   r<   )r2   r=   r>   rJ   Úpartr%   r%   r&   Útest_proc_cmdline»   s    
z"_BaseFSAPIsTests.test_proc_cmdlinec          	   C   sj   | j d }|  t|¡ t|ƒ t|ƒ t ¡ }| ¡ }W d Q R X |  | ¡ t	¡ |  
¡ rf|  ||¡ d S )NÚ2)r.   Ú
addCleanupr   r   r   r6   r7   Úcwdr:   r;   r5   r<   )r2   Údnamer>   rO   r%   r%   r&   Útest_proc_cwdÄ   s    

z_BaseFSAPIsTests.test_proc_cwdc          	   C   sŽ   t  ¡ }t| ¡ ƒ}t| jdƒ t| ¡ ƒ}W d Q R X ||  ¡ j}|  |t	¡ t
rd|sd|  d¡S |  ¡ rŠ|  tj |¡tj | j¡¡ d S )NÚrbzopen_files on BSD is broken)r6   r7   ÚsetZ
open_filesÚopenr.   Úpopr$   r:   r;   r   ZskipTestr5   r<   rC   Únormcase)r2   r>   ÚstartÚnewr$   r%   r%   r&   Útest_proc_open_filesÏ   s    
z%_BaseFSAPIsTests.test_proc_open_filesz
POSIX onlyc          
   C   s¢   t j | j¡}t|d€}yt|ƒ}W n& tk
rL   tr>‚ n
t 	d¡‚Y nX t
|ƒ8 t ¡  d¡d }|  |jt¡ tsŠ|  |j|¡ W d Q R X W d Q R X d S )N)Úsuffixznot supportedÚunixr   )rC   r$   rG   r.   r    r   r(   r   r   ÚSkipTestr   r6   r7   Zconnectionsr:   Úladdrr;   r   r<   )r2   rZ   r)   ÚsockÚconnr%   r%   r&   Útest_proc_connectionsÝ   s    
z&_BaseFSAPIsTests.test_proc_connectionszcan't list UNIX socketsc          
   C   s¬   dd„ }t j | j¡}t|d‚}yt|ƒ}W n& tk
rT   trF‚ n
t 	d¡‚Y nX t
|ƒ: tjdd}ts”||ƒ}|  |jt¡ |  |j|¡ W d Q R X W d Q R X d S )Nc             S   s2   x$| D ]}t j |j¡ t¡r|S qW tdƒ‚d S )Nzconnection not found)rC   r$   rG   r]   Ú
startswithr   Ú
ValueError)Úconsr_   r%   r%   r&   Ú	find_sockó   s    
z8_BaseFSAPIsTests.test_net_connections.<locals>.find_sock)rZ   znot supportedr[   )Zkind)rC   r$   rG   r.   r    r   r(   r   r   r\   r   r6   Znet_connectionsr   r:   r]   r;   r<   )r2   rd   rZ   r)   r^   rc   r_   r%   r%   r&   Útest_net_connectionsï   s    
z%_BaseFSAPIsTests.test_net_connectionsc             C   s,   | j d }|  t|¡ t|ƒ t |¡ d S )NrM   )r.   rN   r   r   r6   Z
disk_usage)r2   rP   r%   r%   r&   Útest_disk_usage
  s    
z _BaseFSAPIsTests.test_disk_usageznot supportedz&ctypes does not support unicode on PY2c          	      sv   t | jd`}dd„ ‰ ‡ fdd„t ¡  ¡ D ƒ}dd„ |D ƒ}|  ˆ |ƒ|¡ x|D ]}|  |t¡ qTW W d Q R X d S )N)Z
dst_prefixc             S   s   t j t j | ¡¡S )N)rC   r$   ÚrealpathrV   )r>   r%   r%   r&   Únormpath  s    z3_BaseFSAPIsTests.test_memory_maps.<locals>.normpathc                s   g | ]}ˆ |j ƒ‘qS r%   )r$   )Ú.0Úx)rh   r%   r&   ú
<listcomp>  s   z5_BaseFSAPIsTests.test_memory_maps.<locals>.<listcomp>c             S   s   g | ]}t |kr|‘qS r%   )r   )ri   rj   r%   r%   r&   rk     s    )r   r.   r6   r7   Zmemory_mapsZassertInr:   r;   )r2   Z
funky_pathZlibpathsr$   r%   )rh   r&   Útest_memory_maps  s    

z!_BaseFSAPIsTests.test_memory_maps)Ú__name__Ú
__module__Ú__qualname__r.   Úclassmethodr0   r1   r3   r5   r?   rI   rL   rQ   rY   r   ÚskipIfr   r`   r   r   re   rf   r   r   rl   r%   r%   r%   r&   r-      s"   	r-   zunreliable on PYPY + TRAVISzunreliable on TRAVISzASCII fsz"subprocess can't deal with unicodec               @   s    e Zd ZdZeZedd„ ƒZdS )Ú
TestFSAPIsz1Test FS APIs with a funky, valid, UTF8 path name.c          	   C   sN   t rdS t| jtƒrdntdƒ}t ¡  t d¡ | jt 	|¡kS Q R X d S )NTÚ.Úignore)
r   Ú
isinstancer.   r;   r	   ÚwarningsÚcatch_warningsÚsimplefilterrC   Úlistdir)r/   Úherer%   r%   r&   r5   +  s    

z"TestFSAPIs.expect_exact_path_matchN)rm   rn   ro   Ú__doc__r   r.   rp   r5   r%   r%   r%   r&   rr   "  s   rr   z*subprocess can't deal with invalid unicodec               @   s    e Zd ZdZeZedd„ ƒZdS )ÚTestFSAPIsWithInvalidPathz-Test FS APIs with a funky, invalid path name.c             C   s   dS )NTr%   )r/   r%   r%   r&   r5   @  s    z1TestFSAPIsWithInvalidPath.expect_exact_path_matchN)rm   rn   ro   r{   ÚINVALID_NAMEr.   rp   r5   r%   r%   r%   r&   r|   8  s   r|   zWINDOWS onlyc               @   s   e Zd Zdd„ ZdS )ÚTestWinProcessNamec          	   C   sF   t jdt t ¡ ¡d$}|  t ¡  ¡ t	¡ |j
s8t‚W d Q R X d S )Nz psutil._psplatform.cext.proc_exe)r@   )r   rA   r6   rB   rC   rD   r:   r7   r)   r;   rE   rF   )r2   rH   r%   r%   r&   Útest_name_typeI  s    z!TestWinProcessName.test_name_typeN)rm   rn   ro   r   r%   r%   r%   r&   r~   F  s   r~   c               @   s.   e Zd ZdZdd„ Ze e d¡dd„ ƒZdS )ÚTestNonFSAPISz&Unicode tests for non fs-related APIs.c             C   s
   t ƒ  d S )N)r   )r2   r%   r%   r&   r3   [  s    zTestNonFSAPIS.tearDownznot supportedc             C   s~   t j ¡ }trtnd}||d< t|d}t |j¡}| ¡ }x,| 	¡ D ] \}}|  
|t¡ |  
|t¡ qFW |  |d |¡ d S )Nõ   Ã¨Z	FUNNY_ARG)Úenv)rC   ÚenvironÚcopyr   r   r   r6   r7   r8   Úitemsr:   r;   r<   )r2   r‚   Z	funky_strZsprocr>   ÚkÚvr%   r%   r&   Útest_proc_environ^  s    

zTestNonFSAPIS.test_proc_environN)	rm   rn   ro   r{   r3   r   rq   r   rˆ   r%   r%   r%   r&   r€   X  s   r€   Ú__main__)6r{   rC   r"   rv   Ú
contextlibr   r6   r   r   r   r   r   Zpsutil._compatr   r	   Zpsutil.testsr
   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r!   r   r   r   r   r   r   r    r*   ÚencodeÚdecoder}   Úobjectr-   rq   ZTestCaserr   r|   r~   r€   rm   Ú__file__r%   r%   r%   r&   Ú<module>5   sv   
 



