PNG  IHDRX cHRMz&u0`:pQ<bKGD pHYsodtIME MeqIDATxw]Wug^Qd˶ 6`!N:!@xI~)%7%@Bh&`lnjVF29gΨ4E$|>cɚ{gk= %,a KX%,a KX%,a KX%,a KX%,a KX%,a KX%, b` ǟzeאfp]<!SJmɤY޲ڿ,%c ~ع9VH.!Ͳz&QynֺTkRR.BLHi٪:l;@(!MԴ=žI,:o&N'Kù\vRmJ雵֫AWic H@" !: Cé||]k-Ha oݜ:y F())u]aG7*JV@J415p=sZH!=!DRʯvɱh~V\}v/GKY$n]"X"}t@ xS76^[bw4dsce)2dU0 CkMa-U5tvLƀ~mlMwfGE/-]7XAƟ`׮g ewxwC4\[~7@O-Q( a*XGƒ{ ՟}$_y3tĐƤatgvێi|K=uVyrŲlLӪuܿzwk$m87k( `múcE)"@rK( z4$D; 2kW=Xb$V[Ru819קR~qloѱDyįݎ*mxw]y5e4K@ЃI0A D@"BDk_)N\8͜9dz"fK0zɿvM /.:2O{ Nb=M=7>??Zuo32 DLD@D| &+֎C #B8ַ`bOb $D#ͮҪtx]%`ES`Ru[=¾!@Od37LJ0!OIR4m]GZRJu$‡c=%~s@6SKy?CeIh:[vR@Lh | (BhAMy=݃  G"'wzn޺~8ԽSh ~T*A:xR[ܹ?X[uKL_=fDȊ؂p0}7=D$Ekq!/t.*2ʼnDbŞ}DijYaȲ(""6HA;:LzxQ‘(SQQ}*PL*fc\s `/d'QXW, e`#kPGZuŞuO{{wm[&NBTiiI0bukcA9<4@SӊH*؎4U/'2U5.(9JuDfrޱtycU%j(:RUbArLֺN)udA':uGQN"-"Is.*+k@ `Ojs@yU/ H:l;@yyTn}_yw!VkRJ4P)~y#)r,D =ě"Q]ci'%HI4ZL0"MJy 8A{ aN<8D"1#IJi >XjX֔#@>-{vN!8tRݻ^)N_╗FJEk]CT՟ YP:_|H1@ CBk]yKYp|og?*dGvzنzӴzjֺNkC~AbZƷ`.H)=!QͷVTT(| u78y֮}|[8-Vjp%2JPk[}ԉaH8Wpqhwr:vWª<}l77_~{s۴V+RCģ%WRZ\AqHifɤL36: #F:p]Bq/z{0CU6ݳEv_^k7'>sq*+kH%a`0ԣisqにtү04gVgW΂iJiS'3w.w}l6MC2uԯ|>JF5`fV5m`Y**Db1FKNttu]4ccsQNnex/87+}xaUW9y>ͯ骵G{䩓Գ3+vU}~jJ.NFRD7<aJDB1#ҳgSb,+CS?/ VG J?|?,2#M9}B)MiE+G`-wo߫V`fio(}S^4e~V4bHOYb"b#E)dda:'?}׮4繏`{7Z"uny-?ǹ;0MKx{:_pÚmFמ:F " .LFQLG)Q8qN q¯¯3wOvxDb\. BKD9_NN &L:4D{mm o^tֽ:q!ƥ}K+<"m78N< ywsard5+вz~mnG)=}lYݧNj'QJS{S :UYS-952?&O-:W}(!6Mk4+>A>j+i|<<|;ر^߉=HE|V#F)Emm#}/"y GII웻Jі94+v뾧xu~5C95~ūH>c@덉pʃ1/4-A2G%7>m;–Y,cyyaln" ?ƻ!ʪ<{~h~i y.zZB̃/,雋SiC/JFMmBH&&FAbϓO^tubbb_hZ{_QZ-sύodFgO(6]TJA˯#`۶ɟ( %$&+V'~hiYy>922 Wp74Zkq+Ovn錄c>8~GqܲcWꂎz@"1A.}T)uiW4="jJ2W7mU/N0gcqܗOO}?9/wìXžΏ0 >֩(V^Rh32!Hj5`;O28؇2#ݕf3 ?sJd8NJ@7O0 b־?lldщ̡&|9C.8RTWwxWy46ah嘦mh٤&l zCy!PY?: CJyв]dm4ǜҐR޻RլhX{FƯanшQI@x' ao(kUUuxW_Ñ줮[w8 FRJ(8˼)_mQ _!RJhm=!cVmm ?sFOnll6Qk}alY}; "baӌ~M0w,Ggw2W:G/k2%R,_=u`WU R.9T"v,<\Ik޽/2110Ӿxc0gyC&Ny޽JҢrV6N ``یeA16"J³+Rj*;BϜkZPJaÍ<Jyw:NP8/D$ 011z֊Ⱳ3ι֘k1V_"h!JPIΣ'ɜ* aEAd:ݺ>y<}Lp&PlRfTb1]o .2EW\ͮ]38؋rTJsǏP@芎sF\> P^+dYJLbJ C-xϐn> ι$nj,;Ǖa FU *择|h ~izť3ᤓ`K'-f tL7JK+vf2)V'-sFuB4i+m+@My=O҈0"|Yxoj,3]:cо3 $#uŘ%Y"y죯LebqtҢVzq¼X)~>4L׶m~[1_k?kxֺQ`\ |ٛY4Ѯr!)N9{56(iNq}O()Em]=F&u?$HypWUeB\k]JɩSع9 Zqg4ZĊo oMcjZBU]B\TUd34ݝ~:7ڶSUsB0Z3srx 7`:5xcx !qZA!;%͚7&P H<WL!džOb5kF)xor^aujƍ7 Ǡ8/p^(L>ὴ-B,{ۇWzֺ^k]3\EE@7>lYBȝR.oHnXO/}sB|.i@ɥDB4tcm,@ӣgdtJ!lH$_vN166L__'Z)y&kH;:,Y7=J 9cG) V\hjiE;gya~%ks_nC~Er er)muuMg2;֫R)Md) ,¶ 2-wr#F7<-BBn~_(o=KO㭇[Xv eN_SMgSҐ BS헃D%g_N:/pe -wkG*9yYSZS.9cREL !k}<4_Xs#FmҶ:7R$i,fi!~' # !6/S6y@kZkZcX)%5V4P]VGYq%H1!;e1MV<!ϐHO021Dp= HMs~~a)ަu7G^];git!Frl]H/L$=AeUvZE4P\.,xi {-~p?2b#amXAHq)MWǾI_r`S Hz&|{ +ʖ_= (YS(_g0a03M`I&'9vl?MM+m~}*xT۲(fY*V4x@29s{DaY"toGNTO+xCAO~4Ϳ;p`Ѫ:>Ҵ7K 3}+0 387x\)a"/E>qpWB=1 ¨"MP(\xp߫́A3+J] n[ʼnӼaTbZUWb={~2ooKױӰp(CS\S筐R*JغV&&"FA}J>G֐p1ٸbk7 ŘH$JoN <8s^yk_[;gy-;߉DV{c B yce% aJhDȶ 2IdйIB/^n0tNtџdcKj4϶v~- CBcgqx9= PJ) dMsjpYB] GD4RDWX +h{y`,3ꊕ$`zj*N^TP4L:Iz9~6s) Ga:?y*J~?OrMwP\](21sZUD ?ܟQ5Q%ggW6QdO+\@ ̪X'GxN @'4=ˋ+*VwN ne_|(/BDfj5(Dq<*tNt1х!MV.C0 32b#?n0pzj#!38}޴o1KovCJ`8ŗ_"]] rDUy޲@ Ȗ-;xџ'^Y`zEd?0„ DAL18IS]VGq\4o !swV7ˣι%4FѮ~}6)OgS[~Q vcYbL!wG3 7띸*E Pql8=jT\꘿I(z<[6OrR8ºC~ډ]=rNl[g|v TMTղb-o}OrP^Q]<98S¤!k)G(Vkwyqyr޽Nv`N/e p/~NAOk \I:G6]4+K;j$R:Mi #*[AȚT,ʰ,;N{HZTGMoּy) ]%dHء9Պ䠬|<45,\=[bƟ8QXeB3- &dҩ^{>/86bXmZ]]yޚN[(WAHL$YAgDKp=5GHjU&99v簪C0vygln*P)9^͞}lMuiH!̍#DoRBn9l@ xA/_v=ȺT{7Yt2N"4!YN`ae >Q<XMydEB`VU}u]嫇.%e^ánE87Mu\t`cP=AD/G)sI"@MP;)]%fH9'FNsj1pVhY&9=0pfuJ&gޤx+k:!r˭wkl03׼Ku C &ѓYt{.O.zҏ z}/tf_wEp2gvX)GN#I ݭ߽v/ .& и(ZF{e"=V!{zW`, ]+LGz"(UJp|j( #V4, 8B 0 9OkRrlɱl94)'VH9=9W|>PS['G(*I1==C<5"Pg+x'K5EMd؞Af8lG ?D FtoB[je?{k3zQ vZ;%Ɠ,]E>KZ+T/ EJxOZ1i #T<@ I}q9/t'zi(EMqw`mYkU6;[t4DPeckeM;H}_g pMww}k6#H㶏+b8雡Sxp)&C $@'b,fPߑt$RbJ'vznuS ~8='72_`{q纶|Q)Xk}cPz9p7O:'|G~8wx(a 0QCko|0ASD>Ip=4Q, d|F8RcU"/KM opKle M3#i0c%<7׿p&pZq[TR"BpqauIp$ 8~Ĩ!8Սx\ւdT>>Z40ks7 z2IQ}ItԀ<-%S⍤};zIb$I 5K}Q͙D8UguWE$Jh )cu4N tZl+[]M4k8֦Zeq֮M7uIqG 1==tLtR,ƜSrHYt&QP윯Lg' I,3@P'}'R˪e/%-Auv·ñ\> vDJzlӾNv5:|K/Jb6KI9)Zh*ZAi`?S {aiVDԲuy5W7pWeQJk֤#5&V<̺@/GH?^τZL|IJNvI:'P=Ϛt"¨=cud S Q.Ki0 !cJy;LJR;G{BJy޺[^8fK6)=yʊ+(k|&xQ2`L?Ȓ2@Mf 0C`6-%pKpm')c$׻K5[J*U[/#hH!6acB JA _|uMvDyk y)6OPYjœ50VT K}cǻP[ $:]4MEA.y)|B)cf-A?(e|lɉ#P9V)[9t.EiQPDѠ3ϴ;E:+Օ t ȥ~|_N2,ZJLt4! %ա]u {+=p.GhNcŞQI?Nd'yeh n7zi1DB)1S | S#ًZs2|Ɛy$F SxeX{7Vl.Src3E℃Q>b6G ўYCmtկ~=K0f(=LrAS GN'ɹ9<\!a`)֕y[uՍ[09` 9 +57ts6}b4{oqd+J5fa/,97J#6yν99mRWxJyѡyu_TJc`~W>l^q#Ts#2"nD1%fS)FU w{ܯ R{ ˎ󅃏џDsZSQS;LV;7 Od1&1n$ N /.q3~eNɪ]E#oM~}v֯FڦwyZ=<<>Xo稯lfMFV6p02|*=tV!c~]fa5Y^Q_WN|Vs 0ҘދU97OI'N2'8N֭fgg-}V%y]U4 峧p*91#9U kCac_AFңĪy뚇Y_AiuYyTTYЗ-(!JFLt›17uTozc. S;7A&&<ԋ5y;Ro+:' *eYJkWR[@F %SHWP 72k4 qLd'J "zB6{AC0ƁA6U.'F3:Ȅ(9ΜL;D]m8ڥ9}dU "v!;*13Rg^fJyShyy5auA?ɩGHRjo^]׽S)Fm\toy 4WQS@mE#%5ʈfFYDX ~D5Ϡ9tE9So_aU4?Ѽm%&c{n>.KW1Tlb}:j uGi(JgcYj0qn+>) %\!4{LaJso d||u//P_y7iRJ߬nHOy) l+@$($VFIQ9%EeKʈU. ia&FY̒mZ=)+qqoQn >L!qCiDB;Y<%} OgBxB!ØuG)WG9y(Ą{_yesuZmZZey'Wg#C~1Cev@0D $a@˲(.._GimA:uyw֬%;@!JkQVM_Ow:P.s\)ot- ˹"`B,e CRtaEUP<0'}r3[>?G8xU~Nqu;Wm8\RIkբ^5@k+5(By'L&'gBJ3ݶ!/㮻w҅ yqPWUg<e"Qy*167΃sJ\oz]T*UQ<\FԎ`HaNmڜ6DysCask8wP8y9``GJ9lF\G g's Nn͵MLN֪u$| /|7=]O)6s !ĴAKh]q_ap $HH'\1jB^s\|- W1:=6lJBqjY^LsPk""`]w)󭃈,(HC ?䔨Y$Sʣ{4Z+0NvQkhol6C.婧/u]FwiVjZka&%6\F*Ny#8O,22+|Db~d ~Çwc N:FuuCe&oZ(l;@ee-+Wn`44AMK➝2BRՈt7g*1gph9N) *"TF*R(#'88pm=}X]u[i7bEc|\~EMn}P瘊J)K.0i1M6=7'_\kaZ(Th{K*GJyytw"IO-PWJk)..axӝ47"89Cc7ĐBiZx 7m!fy|ϿF9CbȩV 9V-՛^pV̌ɄS#Bv4-@]Vxt-Z, &ֺ*diؠ2^VXbs֔Ìl.jQ]Y[47gj=幽ex)A0ip׳ W2[ᎇhuE^~q흙L} #-b۸oFJ_QP3r6jr+"nfzRJTUqoaۍ /$d8Mx'ݓ= OՃ| )$2mcM*cЙj}f };n YG w0Ia!1Q.oYfr]DyISaP}"dIӗթO67jqR ҊƐƈaɤGG|h;t]䗖oSv|iZqX)oalv;۩meEJ\!8=$4QU4Xo&VEĊ YS^E#d,yX_> ۘ-e\ "Wa6uLĜZi`aD9.% w~mB(02G[6y.773a7 /=o7D)$Z 66 $bY^\CuP. (x'"J60׿Y:Oi;F{w佩b+\Yi`TDWa~|VH)8q/=9!g߆2Y)?ND)%?Ǐ`k/sn:;O299yB=a[Ng 3˲N}vLNy;*?x?~L&=xyӴ~}q{qE*IQ^^ͧvü{Huu=R|>JyUlZV, B~/YF!Y\u_ݼF{_C)LD]m {H 0ihhadd nUkf3oٺCvE\)QJi+֥@tDJkB$1!Đr0XQ|q?d2) Ӣ_}qv-< FŊ߫%roppVBwü~JidY4:}L6M7f٬F "?71<2#?Jyy4뷢<_a7_=Q E=S1И/9{+93֮E{ǂw{))?maÆm(uLE#lïZ  ~d];+]h j?!|$F}*"4(v'8s<ŏUkm7^7no1w2ؗ}TrͿEk>p'8OB7d7R(A 9.*Mi^ͳ; eeUwS+C)uO@ =Sy]` }l8^ZzRXj[^iUɺ$tj))<sbDJfg=Pk_{xaKo1:-uyG0M ԃ\0Lvuy'ȱc2Ji AdyVgVh!{]/&}}ċJ#%d !+87<;qN޼Nفl|1N:8ya  8}k¾+-$4FiZYÔXk*I&'@iI99)HSh4+2G:tGhS^繿 Kتm0 вDk}֚+QT4;sC}rՅE,8CX-e~>G&'9xpW,%Fh,Ry56Y–hW-(v_,? ; qrBk4-V7HQ;ˇ^Gv1JVV%,ik;D_W!))+BoS4QsTM;gt+ndS-~:11Sgv!0qRVh!"Ȋ(̦Yl.]PQWgٳE'`%W1{ndΗBk|Ž7ʒR~,lnoa&:ü$ 3<a[CBݮwt"o\ePJ=Hz"_c^Z.#ˆ*x z̝grY]tdkP*:97YľXyBkD4N.C_[;F9`8& !AMO c `@BA& Ost\-\NX+Xp < !bj3C&QL+*&kAQ=04}cC!9~820G'PC9xa!w&bo_1 Sw"ܱ V )Yl3+ס2KoXOx]"`^WOy :3GO0g;%Yv㐫(R/r (s } u B &FeYZh0y> =2<Ϟc/ -u= c&׭,.0"g"7 6T!vl#sc>{u/Oh Bᾈ)۴74]x7 gMӒ"d]U)}" v4co[ ɡs 5Gg=XR14?5A}D "b{0$L .\4y{_fe:kVS\\O]c^W52LSBDM! C3Dhr̦RtArx4&agaN3Cf<Ԉp4~ B'"1@.b_/xQ} _߃҉/gٓ2Qkqp0շpZ2fԫYz< 4L.Cyυι1t@鎫Fe sYfsF}^ V}N<_`p)alٶ "(XEAVZ<)2},:Ir*#m_YӼ R%a||EƼIJ,,+f"96r/}0jE/)s)cjW#w'Sʯ5<66lj$a~3Kʛy 2:cZ:Yh))+a߭K::N,Q F'qB]={.]h85C9cr=}*rk?vwV렵ٸW Rs%}rNAkDv|uFLBkWY YkX מ|)1!$#3%y?pF<@<Rr0}: }\J [5FRxY<9"SQdE(Q*Qʻ)q1E0B_O24[U'],lOb ]~WjHޏTQ5Syu wq)xnw8~)c 쫬gٲߠ H% k5dƝk> kEj,0% b"vi2Wس_CuK)K{n|>t{P1򨾜j>'kEkƗBg*H%'_aY6Bn!TL&ɌOb{c`'d^{t\i^[uɐ[}q0lM˕G:‚4kb祔c^:?bpg… +37stH:0}en6x˟%/<]BL&* 5&fK9Mq)/iyqtA%kUe[ڛKN]Ě^,"`/ s[EQQm?|XJ߅92m]G.E΃ח U*Cn.j_)Tѧj̿30ڇ!A0=͜ar I3$C^-9#|pk!)?7.x9 @OO;WƝZBFU keZ75F6Tc6"ZȚs2y/1 ʵ:u4xa`C>6Rb/Yм)^=+~uRd`/|_8xbB0?Ft||Z\##|K 0>>zxv8۴吅q 8ĥ)"6>~\8:qM}#͚'ĉ#p\׶ l#bA?)|g g9|8jP(cr,BwV (WliVxxᡁ@0Okn;ɥh$_ckCgriv}>=wGzβ KkBɛ[˪ !J)h&k2%07δt}!d<9;I&0wV/ v 0<H}L&8ob%Hi|޶o&h1L|u֦y~󛱢8fٲUsւ)0oiFx2}X[zVYr_;N(w]_4B@OanC?gĦx>мgx>ΛToZoOMp>40>V Oy V9iq!4 LN,ˢu{jsz]|"R޻&'ƚ{53ўFu(<٪9:΋]B;)B>1::8;~)Yt|0(pw2N%&X,URBK)3\zz&}ax4;ǟ(tLNg{N|Ǽ\G#C9g$^\}p?556]/RP.90 k,U8/u776s ʪ_01چ|\N 0VV*3H鴃J7iI!wG_^ypl}r*jɤSR 5QN@ iZ#1ٰy;_\3\BQQ x:WJv츟ٯ$"@6 S#qe딇(/P( Dy~TOϻ<4:-+F`0||;Xl-"uw$Цi󼕝mKʩorz"mϺ$F:~E'ҐvD\y?Rr8_He@ e~O,T.(ފR*cY^m|cVR[8 JҡSm!ΆԨb)RHG{?MpqrmN>߶Y)\p,d#xۆWY*,l6]v0h15M˙MS8+EdI='LBJIH7_9{Caз*Lq,dt >+~ّeʏ?xԕ4bBAŚjﵫ!'\Ը$WNvKO}ӽmSşذqsOy?\[,d@'73'j%kOe`1.g2"e =YIzS2|zŐƄa\U,dP;jhhhaxǶ?КZ՚.q SE+XrbOu%\GتX(H,N^~]JyEZQKceTQ]VGYqnah;y$cQahT&QPZ*iZ8UQQM.qo/T\7X"u?Mttl2Xq(IoW{R^ ux*SYJ! 4S.Jy~ BROS[V|žKNɛP(L6V^|cR7i7nZW1Fd@ Ara{詑|(T*dN]Ko?s=@ |_EvF]׍kR)eBJc" MUUbY6`~V޴dJKß&~'d3i WWWWWW
Current Directory: /opt/imunify360/venv/lib/python3.11/site-packages/psutil/tests
Viewing File: /opt/imunify360/venv/lib/python3.11/site-packages/psutil/tests/test_misc.py
#!/usr/bin/env python3 # -*- coding: utf-8 -*- # Copyright (c) 2009, Giampaolo Rodola'. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. """ Miscellaneous tests. """ import ast import collections import errno import json import os import pickle import socket import stat import sys from psutil import LINUX from psutil import POSIX from psutil import WINDOWS from psutil._common import memoize from psutil._common import memoize_when_activated from psutil._common import supports_ipv6 from psutil._common import wrap_numbers from psutil._compat import PY3 from psutil.tests import APPVEYOR from psutil.tests import CI_TESTING from psutil.tests import HAS_BATTERY from psutil.tests import HAS_MEMORY_MAPS from psutil.tests import HAS_NET_IO_COUNTERS from psutil.tests import HAS_SENSORS_BATTERY from psutil.tests import HAS_SENSORS_FANS from psutil.tests import HAS_SENSORS_TEMPERATURES from psutil.tests import import_module_by_path from psutil.tests import mock from psutil.tests import PsutilTestCase from psutil.tests import PYTHON_EXE from psutil.tests import reload_module from psutil.tests import ROOT_DIR from psutil.tests import SCRIPTS_DIR from psutil.tests import sh from psutil.tests import unittest import psutil import psutil.tests PYTHON_39 = sys.version_info[:2] == (3, 9) # =================================================================== # --- Misc / generic tests. # =================================================================== class TestMisc(PsutilTestCase): def test_process__repr__(self, func=repr): p = psutil.Process(self.spawn_testproc().pid) r = func(p) self.assertIn("psutil.Process", r) self.assertIn("pid=%s" % p.pid, r) self.assertIn("name='%s'" % str(p.name()), r.replace("name=u'", "name='")) self.assertIn("status=", r) self.assertNotIn("exitcode=", r) p.terminate() p.wait() r = func(p) self.assertIn("status='terminated'", r) self.assertIn("exitcode=", r) with mock.patch.object(psutil.Process, "name", side_effect=psutil.ZombieProcess(os.getpid())): p = psutil.Process() r = func(p) self.assertIn("pid=%s" % p.pid, r) self.assertIn("status='zombie'", r) self.assertNotIn("name=", r) with mock.patch.object(psutil.Process, "name", side_effect=psutil.NoSuchProcess(os.getpid())): p = psutil.Process() r = func(p) self.assertIn("pid=%s" % p.pid, r) self.assertIn("terminated", r) self.assertNotIn("name=", r) with mock.patch.object(psutil.Process, "name", side_effect=psutil.AccessDenied(os.getpid())): p = psutil.Process() r = func(p) self.assertIn("pid=%s" % p.pid, r) self.assertNotIn("name=", r) def test_process__str__(self): self.test_process__repr__(func=str) def test_no_such_process__repr__(self, func=repr): self.assertEqual( repr(psutil.NoSuchProcess(321)), "psutil.NoSuchProcess process no longer exists (pid=321)") self.assertEqual( repr(psutil.NoSuchProcess(321, name='foo')), "psutil.NoSuchProcess process no longer exists (pid=321, " "name='foo')") self.assertEqual( repr(psutil.NoSuchProcess(321, msg='foo')), "psutil.NoSuchProcess foo") def test_zombie_process__repr__(self, func=repr): self.assertEqual( repr(psutil.ZombieProcess(321)), "psutil.ZombieProcess process still exists but it's a zombie " "(pid=321)") self.assertEqual( repr(psutil.ZombieProcess(321, name='foo')), "psutil.ZombieProcess process still exists but it's a zombie " "(pid=321, name='foo')") self.assertEqual( repr(psutil.ZombieProcess(321, name='foo', ppid=1)), "psutil.ZombieProcess process still exists but it's a zombie " "(pid=321, name='foo', ppid=1)") self.assertEqual( repr(psutil.ZombieProcess(321, msg='foo')), "psutil.ZombieProcess foo") def test_access_denied__repr__(self, func=repr): self.assertEqual( repr(psutil.AccessDenied(321)), "psutil.AccessDenied (pid=321)") self.assertEqual( repr(psutil.AccessDenied(321, name='foo')), "psutil.AccessDenied (pid=321, name='foo')") self.assertEqual( repr(psutil.AccessDenied(321, msg='foo')), "psutil.AccessDenied foo") def test_timeout_expired__repr__(self, func=repr): self.assertEqual( repr(psutil.TimeoutExpired(321)), "psutil.TimeoutExpired timeout after 321 seconds") self.assertEqual( repr(psutil.TimeoutExpired(321, pid=111)), "psutil.TimeoutExpired timeout after 321 seconds (pid=111)") self.assertEqual( repr(psutil.TimeoutExpired(321, pid=111, name='foo')), "psutil.TimeoutExpired timeout after 321 seconds " "(pid=111, name='foo')") def test_process__eq__(self): p1 = psutil.Process() p2 = psutil.Process() self.assertEqual(p1, p2) p2._ident = (0, 0) self.assertNotEqual(p1, p2) self.assertNotEqual(p1, 'foo') def test_process__hash__(self): s = set([psutil.Process(), psutil.Process()]) self.assertEqual(len(s), 1) def test__all__(self): dir_psutil = dir(psutil) for name in dir_psutil: if name in ('long', 'tests', 'test', 'PermissionError', 'ProcessLookupError'): continue if not name.startswith('_'): try: __import__(name) except ImportError: if name not in psutil.__all__: fun = getattr(psutil, name) if fun is None: continue if (fun.__doc__ is not None and 'deprecated' not in fun.__doc__.lower()): self.fail('%r not in psutil.__all__' % name) # Import 'star' will break if __all__ is inconsistent, see: # https://github.com/giampaolo/psutil/issues/656 # Can't do `from psutil import *` as it won't work on python 3 # so we simply iterate over __all__. for name in psutil.__all__: self.assertIn(name, dir_psutil) def test_version(self): self.assertEqual('.'.join([str(x) for x in psutil.version_info]), psutil.__version__) def test_process_as_dict_no_new_names(self): # See https://github.com/giampaolo/psutil/issues/813 p = psutil.Process() p.foo = '1' self.assertNotIn('foo', p.as_dict()) def test_memoize(self): @memoize def foo(*args, **kwargs): "foo docstring" calls.append(None) return (args, kwargs) calls = [] # no args for x in range(2): ret = foo() expected = ((), {}) self.assertEqual(ret, expected) self.assertEqual(len(calls), 1) # with args for x in range(2): ret = foo(1) expected = ((1, ), {}) self.assertEqual(ret, expected) self.assertEqual(len(calls), 2) # with args + kwargs for x in range(2): ret = foo(1, bar=2) expected = ((1, ), {'bar': 2}) self.assertEqual(ret, expected) self.assertEqual(len(calls), 3) # clear cache foo.cache_clear() ret = foo() expected = ((), {}) self.assertEqual(ret, expected) self.assertEqual(len(calls), 4) # docstring self.assertEqual(foo.__doc__, "foo docstring") def test_memoize_when_activated(self): class Foo: @memoize_when_activated def foo(self): calls.append(None) f = Foo() calls = [] f.foo() f.foo() self.assertEqual(len(calls), 2) # activate calls = [] f.foo.cache_activate(f) f.foo() f.foo() self.assertEqual(len(calls), 1) # deactivate calls = [] f.foo.cache_deactivate(f) f.foo() f.foo() self.assertEqual(len(calls), 2) def test_parse_environ_block(self): from psutil._common import parse_environ_block def k(s): return s.upper() if WINDOWS else s self.assertEqual(parse_environ_block("a=1\0"), {k("a"): "1"}) self.assertEqual(parse_environ_block("a=1\0b=2\0\0"), {k("a"): "1", k("b"): "2"}) self.assertEqual(parse_environ_block("a=1\0b=\0\0"), {k("a"): "1", k("b"): ""}) # ignore everything after \0\0 self.assertEqual(parse_environ_block("a=1\0b=2\0\0c=3\0"), {k("a"): "1", k("b"): "2"}) # ignore everything that is not an assignment self.assertEqual(parse_environ_block("xxx\0a=1\0"), {k("a"): "1"}) self.assertEqual(parse_environ_block("a=1\0=b=2\0"), {k("a"): "1"}) # do not fail if the block is incomplete self.assertEqual(parse_environ_block("a=1\0b=2"), {k("a"): "1"}) def test_supports_ipv6(self): self.addCleanup(supports_ipv6.cache_clear) if supports_ipv6(): with mock.patch('psutil._common.socket') as s: s.has_ipv6 = False supports_ipv6.cache_clear() assert not supports_ipv6() supports_ipv6.cache_clear() with mock.patch('psutil._common.socket.socket', side_effect=socket.error) as s: assert not supports_ipv6() assert s.called supports_ipv6.cache_clear() with mock.patch('psutil._common.socket.socket', side_effect=socket.gaierror) as s: assert not supports_ipv6() supports_ipv6.cache_clear() assert s.called supports_ipv6.cache_clear() with mock.patch('psutil._common.socket.socket.bind', side_effect=socket.gaierror) as s: assert not supports_ipv6() supports_ipv6.cache_clear() assert s.called else: with self.assertRaises(Exception): sock = socket.socket(socket.AF_INET6, socket.SOCK_STREAM) try: sock.bind(("::1", 0)) finally: sock.close() def test_isfile_strict(self): from psutil._common import isfile_strict this_file = os.path.abspath(__file__) assert isfile_strict(this_file) assert not isfile_strict(os.path.dirname(this_file)) with mock.patch('psutil._common.os.stat', side_effect=OSError(errno.EPERM, "foo")): self.assertRaises(OSError, isfile_strict, this_file) with mock.patch('psutil._common.os.stat', side_effect=OSError(errno.EACCES, "foo")): self.assertRaises(OSError, isfile_strict, this_file) with mock.patch('psutil._common.os.stat', side_effect=OSError(errno.ENOENT, "foo")): assert not isfile_strict(this_file) with mock.patch('psutil._common.stat.S_ISREG', return_value=False): assert not isfile_strict(this_file) def test_serialization(self): def check(ret): if json is not None: json.loads(json.dumps(ret)) a = pickle.dumps(ret) b = pickle.loads(a) self.assertEqual(ret, b) check(psutil.Process().as_dict()) check(psutil.virtual_memory()) check(psutil.swap_memory()) check(psutil.cpu_times()) check(psutil.cpu_times_percent(interval=0)) check(psutil.net_io_counters()) if LINUX and not os.path.exists('/proc/diskstats'): pass else: if not APPVEYOR: check(psutil.disk_io_counters()) check(psutil.disk_partitions()) check(psutil.disk_usage(os.getcwd())) check(psutil.users()) def test_setup_script(self): setup_py = os.path.join(ROOT_DIR, 'setup.py') if CI_TESTING and not os.path.exists(setup_py): return self.skipTest("can't find setup.py") module = import_module_by_path(setup_py) self.assertRaises(SystemExit, module.setup) self.assertEqual(module.get_version(), psutil.__version__) def test_ad_on_process_creation(self): # We are supposed to be able to instantiate Process also in case # of zombie processes or access denied. with mock.patch.object(psutil.Process, 'create_time', side_effect=psutil.AccessDenied) as meth: psutil.Process() assert meth.called with mock.patch.object(psutil.Process, 'create_time', side_effect=psutil.ZombieProcess(1)) as meth: psutil.Process() assert meth.called with mock.patch.object(psutil.Process, 'create_time', side_effect=ValueError) as meth: with self.assertRaises(ValueError): psutil.Process() assert meth.called def test_sanity_version_check(self): # see: https://github.com/giampaolo/psutil/issues/564 with mock.patch( "psutil._psplatform.cext.version", return_value="0.0.0"): with self.assertRaises(ImportError) as cm: reload_module(psutil) self.assertIn("version conflict", str(cm.exception).lower()) # =================================================================== # --- Tests for wrap_numbers() function. # =================================================================== nt = collections.namedtuple('foo', 'a b c') class TestWrapNumbers(PsutilTestCase): def setUp(self): wrap_numbers.cache_clear() tearDown = setUp def test_first_call(self): input = {'disk1': nt(5, 5, 5)} self.assertEqual(wrap_numbers(input, 'disk_io'), input) def test_input_hasnt_changed(self): input = {'disk1': nt(5, 5, 5)} self.assertEqual(wrap_numbers(input, 'disk_io'), input) self.assertEqual(wrap_numbers(input, 'disk_io'), input) def test_increase_but_no_wrap(self): input = {'disk1': nt(5, 5, 5)} self.assertEqual(wrap_numbers(input, 'disk_io'), input) input = {'disk1': nt(10, 15, 20)} self.assertEqual(wrap_numbers(input, 'disk_io'), input) input = {'disk1': nt(20, 25, 30)} self.assertEqual(wrap_numbers(input, 'disk_io'), input) input = {'disk1': nt(20, 25, 30)} self.assertEqual(wrap_numbers(input, 'disk_io'), input) def test_wrap(self): # let's say 100 is the threshold input = {'disk1': nt(100, 100, 100)} self.assertEqual(wrap_numbers(input, 'disk_io'), input) # first wrap restarts from 10 input = {'disk1': nt(100, 100, 10)} self.assertEqual(wrap_numbers(input, 'disk_io'), {'disk1': nt(100, 100, 110)}) # then it remains the same input = {'disk1': nt(100, 100, 10)} self.assertEqual(wrap_numbers(input, 'disk_io'), {'disk1': nt(100, 100, 110)}) # then it goes up input = {'disk1': nt(100, 100, 90)} self.assertEqual(wrap_numbers(input, 'disk_io'), {'disk1': nt(100, 100, 190)}) # then it wraps again input = {'disk1': nt(100, 100, 20)} self.assertEqual(wrap_numbers(input, 'disk_io'), {'disk1': nt(100, 100, 210)}) # and remains the same input = {'disk1': nt(100, 100, 20)} self.assertEqual(wrap_numbers(input, 'disk_io'), {'disk1': nt(100, 100, 210)}) # now wrap another num input = {'disk1': nt(50, 100, 20)} self.assertEqual(wrap_numbers(input, 'disk_io'), {'disk1': nt(150, 100, 210)}) # and again input = {'disk1': nt(40, 100, 20)} self.assertEqual(wrap_numbers(input, 'disk_io'), {'disk1': nt(190, 100, 210)}) # keep it the same input = {'disk1': nt(40, 100, 20)} self.assertEqual(wrap_numbers(input, 'disk_io'), {'disk1': nt(190, 100, 210)}) def test_changing_keys(self): # Emulate a case where the second call to disk_io() # (or whatever) provides a new disk, then the new disk # disappears on the third call. input = {'disk1': nt(5, 5, 5)} self.assertEqual(wrap_numbers(input, 'disk_io'), input) input = {'disk1': nt(5, 5, 5), 'disk2': nt(7, 7, 7)} self.assertEqual(wrap_numbers(input, 'disk_io'), input) input = {'disk1': nt(8, 8, 8)} self.assertEqual(wrap_numbers(input, 'disk_io'), input) def test_changing_keys_w_wrap(self): input = {'disk1': nt(50, 50, 50), 'disk2': nt(100, 100, 100)} self.assertEqual(wrap_numbers(input, 'disk_io'), input) # disk 2 wraps input = {'disk1': nt(50, 50, 50), 'disk2': nt(100, 100, 10)} self.assertEqual(wrap_numbers(input, 'disk_io'), {'disk1': nt(50, 50, 50), 'disk2': nt(100, 100, 110)}) # disk 2 disappears input = {'disk1': nt(50, 50, 50)} self.assertEqual(wrap_numbers(input, 'disk_io'), input) # then it appears again; the old wrap is supposed to be # gone. input = {'disk1': nt(50, 50, 50), 'disk2': nt(100, 100, 100)} self.assertEqual(wrap_numbers(input, 'disk_io'), input) # remains the same input = {'disk1': nt(50, 50, 50), 'disk2': nt(100, 100, 100)} self.assertEqual(wrap_numbers(input, 'disk_io'), input) # and then wraps again input = {'disk1': nt(50, 50, 50), 'disk2': nt(100, 100, 10)} self.assertEqual(wrap_numbers(input, 'disk_io'), {'disk1': nt(50, 50, 50), 'disk2': nt(100, 100, 110)}) def test_real_data(self): d = {'nvme0n1': (300, 508, 640, 1571, 5970, 1987, 2049, 451751, 47048), 'nvme0n1p1': (1171, 2, 5600256, 1024, 516, 0, 0, 0, 8), 'nvme0n1p2': (54, 54, 2396160, 5165056, 4, 24, 30, 1207, 28), 'nvme0n1p3': (2389, 4539, 5154, 150, 4828, 1844, 2019, 398, 348)} self.assertEqual(wrap_numbers(d, 'disk_io'), d) self.assertEqual(wrap_numbers(d, 'disk_io'), d) # decrease this ↓ d = {'nvme0n1': (100, 508, 640, 1571, 5970, 1987, 2049, 451751, 47048), 'nvme0n1p1': (1171, 2, 5600256, 1024, 516, 0, 0, 0, 8), 'nvme0n1p2': (54, 54, 2396160, 5165056, 4, 24, 30, 1207, 28), 'nvme0n1p3': (2389, 4539, 5154, 150, 4828, 1844, 2019, 398, 348)} out = wrap_numbers(d, 'disk_io') self.assertEqual(out['nvme0n1'][0], 400) # --- cache tests def test_cache_first_call(self): input = {'disk1': nt(5, 5, 5)} wrap_numbers(input, 'disk_io') cache = wrap_numbers.cache_info() self.assertEqual(cache[0], {'disk_io': input}) self.assertEqual(cache[1], {'disk_io': {}}) self.assertEqual(cache[2], {'disk_io': {}}) def test_cache_call_twice(self): input = {'disk1': nt(5, 5, 5)} wrap_numbers(input, 'disk_io') input = {'disk1': nt(10, 10, 10)} wrap_numbers(input, 'disk_io') cache = wrap_numbers.cache_info() self.assertEqual(cache[0], {'disk_io': input}) self.assertEqual( cache[1], {'disk_io': {('disk1', 0): 0, ('disk1', 1): 0, ('disk1', 2): 0}}) self.assertEqual(cache[2], {'disk_io': {}}) def test_cache_wrap(self): # let's say 100 is the threshold input = {'disk1': nt(100, 100, 100)} wrap_numbers(input, 'disk_io') # first wrap restarts from 10 input = {'disk1': nt(100, 100, 10)} wrap_numbers(input, 'disk_io') cache = wrap_numbers.cache_info() self.assertEqual(cache[0], {'disk_io': input}) self.assertEqual( cache[1], {'disk_io': {('disk1', 0): 0, ('disk1', 1): 0, ('disk1', 2): 100}}) self.assertEqual(cache[2], {'disk_io': {'disk1': set([('disk1', 2)])}}) def assert_(): cache = wrap_numbers.cache_info() self.assertEqual( cache[1], {'disk_io': {('disk1', 0): 0, ('disk1', 1): 0, ('disk1', 2): 100}}) self.assertEqual(cache[2], {'disk_io': {'disk1': set([('disk1', 2)])}}) # then it remains the same input = {'disk1': nt(100, 100, 10)} wrap_numbers(input, 'disk_io') cache = wrap_numbers.cache_info() self.assertEqual(cache[0], {'disk_io': input}) assert_() # then it goes up input = {'disk1': nt(100, 100, 90)} wrap_numbers(input, 'disk_io') cache = wrap_numbers.cache_info() self.assertEqual(cache[0], {'disk_io': input}) assert_() # then it wraps again input = {'disk1': nt(100, 100, 20)} wrap_numbers(input, 'disk_io') cache = wrap_numbers.cache_info() self.assertEqual(cache[0], {'disk_io': input}) self.assertEqual( cache[1], {'disk_io': {('disk1', 0): 0, ('disk1', 1): 0, ('disk1', 2): 190}}) self.assertEqual(cache[2], {'disk_io': {'disk1': set([('disk1', 2)])}}) def test_cache_changing_keys(self): input = {'disk1': nt(5, 5, 5)} wrap_numbers(input, 'disk_io') input = {'disk1': nt(5, 5, 5), 'disk2': nt(7, 7, 7)} wrap_numbers(input, 'disk_io') cache = wrap_numbers.cache_info() self.assertEqual(cache[0], {'disk_io': input}) self.assertEqual( cache[1], {'disk_io': {('disk1', 0): 0, ('disk1', 1): 0, ('disk1', 2): 0}}) self.assertEqual(cache[2], {'disk_io': {}}) def test_cache_clear(self): input = {'disk1': nt(5, 5, 5)} wrap_numbers(input, 'disk_io') wrap_numbers(input, 'disk_io') wrap_numbers.cache_clear('disk_io') self.assertEqual(wrap_numbers.cache_info(), ({}, {}, {})) wrap_numbers.cache_clear('disk_io') wrap_numbers.cache_clear('?!?') @unittest.skipIf(not HAS_NET_IO_COUNTERS, 'not supported') def test_cache_clear_public_apis(self): if not psutil.disk_io_counters() or not psutil.net_io_counters(): return self.skipTest("no disks or NICs available") psutil.disk_io_counters() psutil.net_io_counters() caches = wrap_numbers.cache_info() for cache in caches: self.assertIn('psutil.disk_io_counters', cache) self.assertIn('psutil.net_io_counters', cache) psutil.disk_io_counters.cache_clear() caches = wrap_numbers.cache_info() for cache in caches: self.assertIn('psutil.net_io_counters', cache) self.assertNotIn('psutil.disk_io_counters', cache) psutil.net_io_counters.cache_clear() caches = wrap_numbers.cache_info() self.assertEqual(caches, ({}, {}, {})) # =================================================================== # --- Example script tests # =================================================================== @unittest.skipIf(not os.path.exists(SCRIPTS_DIR), "can't locate scripts directory") class TestScripts(PsutilTestCase): """Tests for scripts in the "scripts" directory.""" @staticmethod def assert_stdout(exe, *args, **kwargs): exe = '%s' % os.path.join(SCRIPTS_DIR, exe) cmd = [PYTHON_EXE, exe] for arg in args: cmd.append(arg) try: out = sh(cmd, **kwargs).strip() except RuntimeError as err: if 'AccessDenied' in str(err): return str(err) else: raise assert out, out return out @staticmethod def assert_syntax(exe, args=None): exe = os.path.join(SCRIPTS_DIR, exe) if PY3: f = open(exe, 'rt', encoding='utf8') else: f = open(exe, 'rt') with f: src = f.read() ast.parse(src) def test_coverage(self): # make sure all example scripts have a test method defined meths = dir(self) for name in os.listdir(SCRIPTS_DIR): if name.endswith('.py'): if 'test_' + os.path.splitext(name)[0] not in meths: # self.assert_stdout(name) self.fail('no test defined for %r script' % os.path.join(SCRIPTS_DIR, name)) @unittest.skipIf(not POSIX, "POSIX only") def test_executable(self): for name in os.listdir(SCRIPTS_DIR): if name.endswith('.py'): path = os.path.join(SCRIPTS_DIR, name) if not stat.S_IXUSR & os.stat(path)[stat.ST_MODE]: self.fail('%r is not executable' % path) def test_disk_usage(self): self.assert_stdout('disk_usage.py') def test_free(self): self.assert_stdout('free.py') def test_meminfo(self): self.assert_stdout('meminfo.py') def test_procinfo(self): self.assert_stdout('procinfo.py', str(os.getpid())) @unittest.skipIf(CI_TESTING and not psutil.users(), "no users") def test_who(self): self.assert_stdout('who.py') def test_ps(self): self.assert_stdout('ps.py') def test_pstree(self): self.assert_stdout('pstree.py') def test_netstat(self): self.assert_stdout('netstat.py') def test_ifconfig(self): self.assert_stdout('ifconfig.py') @unittest.skipIf(not HAS_MEMORY_MAPS, "not supported") def test_pmap(self): self.assert_stdout('pmap.py', str(os.getpid())) def test_procsmem(self): if 'uss' not in psutil.Process().memory_full_info()._fields: raise self.skipTest("not supported") self.assert_stdout('procsmem.py') def test_killall(self): self.assert_syntax('killall.py') def test_nettop(self): self.assert_syntax('nettop.py') def test_top(self): self.assert_syntax('top.py') def test_iotop(self): self.assert_syntax('iotop.py') def test_pidof(self): output = self.assert_stdout('pidof.py', psutil.Process().name()) self.assertIn(str(os.getpid()), output) @unittest.skipIf(not WINDOWS, "WINDOWS only") def test_winservices(self): self.assert_stdout('winservices.py') def test_cpu_distribution(self): self.assert_syntax('cpu_distribution.py') @unittest.skipIf(not HAS_SENSORS_TEMPERATURES, "not supported") def test_temperatures(self): if not psutil.sensors_temperatures(): self.skipTest("no temperatures") self.assert_stdout('temperatures.py') @unittest.skipIf(not HAS_SENSORS_FANS, "not supported") def test_fans(self): if not psutil.sensors_fans(): self.skipTest("no fans") self.assert_stdout('fans.py') @unittest.skipIf(not HAS_SENSORS_BATTERY, "not supported") @unittest.skipIf(not HAS_BATTERY, "no battery") def test_battery(self): self.assert_stdout('battery.py') @unittest.skipIf(not HAS_SENSORS_BATTERY, "not supported") @unittest.skipIf(not HAS_BATTERY, "no battery") def test_sensors(self): self.assert_stdout('sensors.py') if __name__ == '__main__': from psutil.tests.runner import run_from_name run_from_name(__file__)