diff --git a/.gitignore b/.gitignore
index 3218e92..d6ddb82 100644
--- a/.gitignore
+++ b/.gitignore
@@ -65,7 +65,6 @@ __pycache__
/server/share/db
/server/share/log
/server/share/replay
-/server/testssh
# for generated files.
@@ -78,7 +77,6 @@ __pycache__
/client/tp_rdp
/server/tp_core/protocol/rdp
/client/tools/tprdp
-/server/tp_core/testssh
/client/tp_assist_win_it_doctor
/dist/client/windows/assist-it-doctor
diff --git a/.idea/encodings.xml b/.idea/encodings.xml
index 7d25301..a363e60 100644
--- a/.idea/encodings.xml
+++ b/.idea/encodings.xml
@@ -30,8 +30,12 @@
+
+
+
+
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 8b9daf5..47ae499 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -36,7 +36,7 @@ endif()
add_subdirectory(server/tp_core/core)
add_subdirectory(server/tp_core/protocol/ssh)
add_subdirectory(server/tp_core/protocol/telnet)
-#add_subdirectory(server/testssh/testssh)
+add_subdirectory(server/tp_core/testssh)
if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/server/tp_core/protocol/rdp")
add_subdirectory(server/tp_core/protocol/rdp)
diff --git a/build/build-py-static.sh b/build/build-py-static.sh
index b501055..296612b 100755
--- a/build/build-py-static.sh
+++ b/build/build-py-static.sh
@@ -3,10 +3,10 @@
################################################################
# Basic settings.
################################################################
-VER_PYTHON="3.7.0"
+VER_PYTHON="3.7.4"
VER_PYTHON_SHORT="3.7"
-VER_OPENSSL="1.0.2p"
-VER_SQLITE="3250000"
+VER_OPENSSL="1.0.2s"
+VER_SQLITE="3290000"
VER_ZLIB="1.2.11"
VER_PYTHON_LIB="${VER_PYTHON_SHORT}m"
@@ -77,7 +77,7 @@ function step_download_files()
dlfile "python source tarball" "https://www.python.org/ftp/python/${VER_PYTHON}/" "Python-${VER_PYTHON}.tgz" ${PATH_DOWNLOAD}
dlfile "openssl source tarball" "https://www.openssl.org/source/" "openssl-${VER_OPENSSL}.tar.gz" ${PATH_DOWNLOAD}
- dlfile "sqlite source tarball" "http://sqlite.org/2018/" "sqlite-autoconf-${VER_SQLITE}.tar.gz" ${PATH_DOWNLOAD}
+ dlfile "sqlite source tarball" "http://sqlite.org/2019/" "sqlite-autoconf-${VER_SQLITE}.tar.gz" ${PATH_DOWNLOAD}
dlfile "zlib source tarball" "https://www.zlib.net/" "zlib-${VER_ZLIB}.tar.gz" ${PATH_DOWNLOAD}
}
diff --git a/client/tp_assist_macos/TP-Assist.xcodeproj/project.pbxproj b/client/tp_assist_macos/TP-Assist.xcodeproj/project.pbxproj
index f40084d..6222092 100644
--- a/client/tp_assist_macos/TP-Assist.xcodeproj/project.pbxproj
+++ b/client/tp_assist_macos/TP-Assist.xcodeproj/project.pbxproj
@@ -381,7 +381,7 @@
};
buildConfigurationList = C149EBF315D5214600B1F558 /* Build configuration list for PBXProject "TP-Assist" */;
compatibilityVersion = "Xcode 10.0";
- developmentRegion = English;
+ developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
diff --git a/client/tp_assist_macos/apple-scripts/scripts/iterm2.applescript b/client/tp_assist_macos/apple-scripts/scripts/iterm2.applescript
index 1caf314..a840cae 100644
--- a/client/tp_assist_macos/apple-scripts/scripts/iterm2.applescript
+++ b/client/tp_assist_macos/apple-scripts/scripts/iterm2.applescript
@@ -6,58 +6,17 @@ on scriptRun(argsCmd, argsProfile, argsTitle)
end scriptRun
on CommandRun(theCmd, theProfile, theTitle)
- tell application "iTerm"
- if it is not running then
- tell application "iTerm"
- activate
- delay 0.5
- try
- close first window
- end try
- end tell
-
- tell application "iTerm"
- try
- create window with profile theProfile
- on error msg
- create window with profile "Default"
- end try
- tell the current window
- tell the current session
- delay 0.5
- set name to theTitle
- set profile to theProfile
- write text theCmd
- delay 0.5
- write text ""
- end tell
- end tell
- end tell
- else
- --assume that iTerm is open and open a new tab
- try
+ try
+ tell application "iTerm"
+ if it is not running then
tell application "iTerm"
activate
- tell the current window
- try
- create tab with profile theProfile
- on error msg
- create tab with profile "Default"
- end try
- tell the current tab
- tell the current session
- delay 0.5
- set name to theTitle
- write text theCmd
- delay 0.5
- write text ""
- end tell
- end tell
- end tell
+ delay 0.5
+ try
+ close first window
+ end try
end tell
- on error msg
- -- if all iTerm windows are closed the app stays open. In this scenario iTerm has
- -- no "current window" and will give an error when trying to create the new tab.
+
tell application "iTerm"
try
create window with profile theProfile
@@ -68,13 +27,59 @@ on CommandRun(theCmd, theProfile, theTitle)
tell the current session
delay 0.5
set name to theTitle
+ set profile to theProfile
write text theCmd
delay 0.5
write text ""
end tell
end tell
end tell
- end try
- end if
- end tell
+ else
+ --assume that iTerm is open and open a new tab
+ try
+ tell application "iTerm"
+ activate
+ tell the current window
+ try
+ create tab with profile theProfile
+ on error msg
+ create tab with profile "Default"
+ end try
+ tell the current tab
+ tell the current session
+ delay 0.5
+ set name to theTitle
+ write text theCmd
+ delay 0.5
+ write text ""
+ end tell
+ end tell
+ end tell
+ end tell
+ on error msg
+ -- if all iTerm windows are closed the app stays open. In this scenario iTerm has
+ -- no "current window" and will give an error when trying to create the new tab.
+ tell application "iTerm"
+ try
+ create window with profile theProfile
+ on error msg
+ create window with profile "Default"
+ end try
+ tell the current window
+ tell the current session
+ delay 0.5
+ set name to theTitle
+ write text theCmd
+ delay 0.5
+ write text ""
+ end tell
+ end tell
+ end tell
+ end try
+ end if
+ end tell
+ on error msg
+ display dialog "ERROR: " & msg
+ end try
+
end CommandRun
diff --git a/client/tp_assist_macos/apple-scripts/scripts/terminal.applescript b/client/tp_assist_macos/apple-scripts/scripts/terminal.applescript
index a61e3ab..33506c7 100644
--- a/client/tp_assist_macos/apple-scripts/scripts/terminal.applescript
+++ b/client/tp_assist_macos/apple-scripts/scripts/terminal.applescript
@@ -1,76 +1,83 @@
on scriptRun(argsCmd, argsProfile, argsTitle)
- set theCmd to (argsCmd)
+ set theCmd to (argsCmd)
set theProfile to (argsProfile)
set theTitle to (argsTitle)
CommandRun(theCmd, theProfile, theTitle)
end scriptRun
on CommandRun(theCmd, theProfile, theTitle)
- tell application "Terminal"
- if it is not running then
- --if this is the first time Terminal is running you have specify window 1
- --if you dont do this you will get two windows and the title wont be set
- activate
- delay 1.0
- set newTerm to do script theCmd in window 1
- set newTerm's current settings to settings set theProfile
- set custom title of front window to theTitle
-
- delay 1.0
- reopen
- activate
- tell application "System Events" to key code 36
- else
- --Terminal is running get the window count
- set windowCount to (count every window)
- if windowCount = 0 then
- --Terminal is running but no windows are open
- --run our script in a new window
+ try
+ tell application "Terminal"
+ if it is not running then
+ --if this is the first time Terminal is running you have specify window 1
+ --if you dont do this you will get two windows and the title wont be set
+ activate
+ delay 3.0
+ set newTerm to do script theCmd in window 1
+ set newTerm's current settings to settings set theProfile
+ set custom title of front window to theTitle
+
+ delay 1.0
reopen
activate
-
- do script theCmd in window 1
-
- set current settings of selected tab of front window to settings set theProfile
- set title displays custom title of front window to true
- set custom title of selected tab of front window to theTitle
-
- delay 1.0
- reopen
- activate
- tell application "System Events" to key code 36
-
+ tell application "System Events" to key code 36
else
- --Terminal is running and we have a window run in a new tab
- reopen
- activate
-
- tell application "System Events"
- tell process "Terminal"
- delay 0.5
- keystroke "t" using {command down}
+ --Terminal is running get the window count
+ set windowCount to (count every window)
+ if windowCount = 0 then
+ --Terminal is running but no windows are open
+ --run our script in a new window
+ reopen
+ activate
+
+ do script theCmd in window 1
+
+ set current settings of selected tab of front window to settings set theProfile
+ set title displays custom title of front window to true
+ set custom title of selected tab of front window to theTitle
+
+ delay 1.0
+ reopen
+ activate
+ tell application "System Events" to key code 36
+
+ else
+ --Terminal is running and we have a window run in a new tab
+ reopen
+ activate
+
+ tell application "System Events"
+ tell process "Terminal"
+ delay 0.5
+ keystroke "t" using {command down}
+ end tell
end tell
- end tell
-
- reopen
- activate
- do script theCmd in front window
-
- set current settings of selected tab of front window to settings set theProfile
- set title displays custom title of front window to true
- set custom title of selected tab of front window to theTitle
-
- delay 1.0
- reopen
- activate
- tell application "System Events" to key code 36
-
+
+ reopen
+ activate
+ do script theCmd in front window
+
+ set current settings of selected tab of front window to settings set theProfile
+ set title displays custom title of front window to true
+ set custom title of selected tab of front window to theTitle
+
+ delay 1.0
+ reopen
+ activate
+ tell application "System Events" to key code 36
+
+ end if
+
+ --set current settings of selected tab of front window to settings set theProfile
+ --set title displays custom title of front window to true
+ --set custom title of selected tab of front window to theTitle
end if
-
-# set current settings of selected tab of front window to settings set theProfile
-# set title displays custom title of front window to true
-# set custom title of selected tab of front window to theTitle
- end if
-
- end tell
+
+ end tell
+
+ on error msg
+ display dialog "ERROR: " & msg
+ end try
+
+
end CommandRun
diff --git a/client/tp_assist_macos/src/Base.lproj/Localizable.strings b/client/tp_assist_macos/src/Base.lproj/Localizable.strings
index e10f545..532603b 100644
--- a/client/tp_assist_macos/src/Base.lproj/Localizable.strings
+++ b/client/tp_assist_macos/src/Base.lproj/Localizable.strings
@@ -3,12 +3,12 @@
TPAssist
*/
-"app_name" = "Teleport助手";
+"app_name" = "Teleport Assist";
//=============================================
// for About Window
//=============================================
"version" = "Version: ";
"app_full_name" = "Teleport Assist for macOS";
-"copyright" = "Copyright © 2017~2018 TP4A. All rights reserved.";
+"copyright" = "Copyright © 2017~2019, tp4a.com. All rights reserved.";
"visit_tp4a_website" = "Visit Teleport Website"
diff --git a/client/tp_assist_macos/src/TP-Assist-Info.plist b/client/tp_assist_macos/src/TP-Assist-Info.plist
index af47fa1..3231d75 100644
--- a/client/tp_assist_macos/src/TP-Assist-Info.plist
+++ b/client/tp_assist_macos/src/TP-Assist-Info.plist
@@ -28,8 +28,10 @@
${MACOSX_DEPLOYMENT_TARGET}
LSUIElement
+ NSAppleEventsUsageDescription
+
NSHumanReadableCopyright
- Copyright © 2017~2018 TP4A. All rights reserved.
+ Copyright © 2017~2019, tp4a.com. All rights reserved.
NSMainNibFile
MainMenu
NSPrincipalClass
diff --git a/client/tp_assist_macos/src/apple-scpt/iterm2.scpt b/client/tp_assist_macos/src/apple-scpt/iterm2.scpt
index 431c2bf..dac4f8e 100644
Binary files a/client/tp_assist_macos/src/apple-scpt/iterm2.scpt and b/client/tp_assist_macos/src/apple-scpt/iterm2.scpt differ
diff --git a/client/tp_assist_macos/src/apple-scpt/terminal.scpt b/client/tp_assist_macos/src/apple-scpt/terminal.scpt
index abda883..98d335e 100644
Binary files a/client/tp_assist_macos/src/apple-scpt/terminal.scpt and b/client/tp_assist_macos/src/apple-scpt/terminal.scpt differ
diff --git a/client/tp_assist_macos/src/zh-Hans.lproj/Localizable.strings b/client/tp_assist_macos/src/zh-Hans.lproj/Localizable.strings
index 1c1fec3..aed4793 100644
--- a/client/tp_assist_macos/src/zh-Hans.lproj/Localizable.strings
+++ b/client/tp_assist_macos/src/zh-Hans.lproj/Localizable.strings
@@ -15,5 +15,5 @@
"about " = "关于 ";
"version" = "版本:";
"app_full_name" = "Teleport助手 - macOS";
-"copyright" = "© 2017~2018 TP4A,保留所有权利。";
+"copyright" = "© 2017~2019,tp4a.com。保留所有权利。";
"visit_tp4a_website" = "访问 Teleport 网站";
diff --git a/server/tp_core/protocol/ssh/stdafx.cpp b/server/tp_core/protocol/ssh/stdafx.cpp
index 1eab518..46afe00 100644
--- a/server/tp_core/protocol/ssh/stdafx.cpp
+++ b/server/tp_core/protocol/ssh/stdafx.cpp
@@ -11,9 +11,9 @@
#ifdef EX_OS_WIN32
# ifdef EX_DEBUG
-# pragma comment(lib, "..\\..\\..\\..\\external\\libssh\\build\\src\\Debug\\ssh.lib")
+# pragma comment(lib, "debug/ssh.lib")
# else
-# pragma comment(lib, "..\\..\\..\\..\\external\\libssh\\build\\src\\Release\\ssh.lib")
+# pragma comment(lib, "release/ssh.lib")
# endif
# pragma comment(lib, "libeay32.lib")
# pragma comment(lib, "ws2_32.lib")
diff --git a/server/tp_core/protocol/ssh/tpssh.vs2017.vcxproj b/server/tp_core/protocol/ssh/tpssh.vs2017.vcxproj
index 250ef8c..c2c091e 100644
--- a/server/tp_core/protocol/ssh/tpssh.vs2017.vcxproj
+++ b/server/tp_core/protocol/ssh/tpssh.vs2017.vcxproj
@@ -66,7 +66,7 @@
Windows
Debug
- ..\..\..\..\external\libssh-win-static\lib;..\..\..\..\external\openssl\out32;%(AdditionalLibraryDirectories)
+ ..\..\..\..\external\libssh\build\src\static;..\..\..\..\external\openssl\out32;%(AdditionalLibraryDirectories)
@@ -86,7 +86,7 @@
true
true
true
- ..\..\..\..\external\libssh-win-static\lib;..\..\..\..\external\openssl\out32;%(AdditionalLibraryDirectories)
+ ..\..\..\..\external\libssh\build\src\static;..\..\..\..\external\openssl\out32;%(AdditionalLibraryDirectories)
@@ -103,10 +103,10 @@
-
-
-
-
+
+
+
+
diff --git a/server/tp_core/protocol/ssh/tpssh.vs2017.vcxproj.filters b/server/tp_core/protocol/ssh/tpssh.vs2017.vcxproj.filters
index 18936c4..6850888 100644
--- a/server/tp_core/protocol/ssh/tpssh.vs2017.vcxproj.filters
+++ b/server/tp_core/protocol/ssh/tpssh.vs2017.vcxproj.filters
@@ -98,24 +98,24 @@
main app
-
- libssh
-
-
- libssh
-
-
- libssh
-
-
- libssh
-
jsoncpp
common
+
+ libssh
+
+
+ libssh
+
+
+ libssh
+
+
+ libssh
+
diff --git a/server/tp_core/testssh/CMakeLists.txt b/server/tp_core/testssh/CMakeLists.txt
new file mode 100644
index 0000000..4a23a43
--- /dev/null
+++ b/server/tp_core/testssh/CMakeLists.txt
@@ -0,0 +1,30 @@
+cmake_minimum_required(VERSION 3.5)
+
+MESSAGE(STATUS "=======================================================")
+MESSAGE(STATUS " testssh")
+MESSAGE(STATUS "=======================================================")
+include(../../../CMakeCfg.txt)
+
+aux_source_directory(. DIR_SRCS)
+aux_source_directory(../../../common/libex/src DIR_SRCS)
+
+list(REMOVE_ITEM DIR_SRCS "./stdafx.cpp")
+
+include_directories(
+ ../../../common/libex/include
+)
+
+include_directories(
+ ${TP_EXTERNAL_RELEASE_DIR}/include
+)
+link_directories(${TP_EXTERNAL_RELEASE_DIR}/lib)
+
+
+add_executable(testssh ${DIR_SRCS})
+
+if (OS_LINUX)
+ set(CMAKE_EXE_LINKER_FLAGS "-export-dynamic")
+ target_link_libraries(testssh ssh ssl crypto dl pthread rt util)
+elseif (OS_MACOS)
+ target_link_libraries(testssh ssh ssl crypto dl pthread util)
+endif ()
diff --git a/server/tp_core/testssh/stdafx.cpp b/server/tp_core/testssh/stdafx.cpp
index ed1318f..846b803 100644
--- a/server/tp_core/testssh/stdafx.cpp
+++ b/server/tp_core/testssh/stdafx.cpp
@@ -6,3 +6,12 @@
// TODO: reference any additional headers you need in STDAFX.H
// and not in this file
+
+#ifdef _DEBUG
+# pragma comment(lib, "debug/ssh.lib")
+#else
+# pragma comment(lib, "release/ssh.lib")
+#endif
+#pragma comment(lib, "libeay32.lib")
+#pragma comment(lib, "ws2_32.lib")
+
diff --git a/server/tp_core/testssh/testssh.cpp b/server/tp_core/testssh/testssh.cpp
index ce34131..4d8c8a4 100644
--- a/server/tp_core/testssh/testssh.cpp
+++ b/server/tp_core/testssh/testssh.cpp
@@ -1,18 +1,10 @@
// testssh.cpp : Defines the entry point for the console application.
//
-#include "stdafx.h"
+//#include "stdafx.h"
#include
-
-#ifdef _DEBUG
-# pragma comment(lib, "debug/ssh.lib")
-#else
-# pragma comment(lib, "release/ssh.lib")
-#endif
-#pragma comment(lib, "libeay32.lib")
-#pragma comment(lib, "ws2_32.lib")
-
+#include
void show_usage() {
printf("Usage:\n");
@@ -81,7 +73,7 @@ int main(int argc, char** argv)
// get banner.
const char* banner = ssh_get_issue_banner(sess);
- if (banner != nullptr) {
+ if (banner != NULL) {
printf("[INFO] server issue banner: %s\n", banner);
}
@@ -92,7 +84,7 @@ int main(int argc, char** argv)
// first try interactive login mode if server allow.
if (!ok && (auth_methods & SSH_AUTH_METHOD_INTERACTIVE) == SSH_AUTH_METHOD_INTERACTIVE) {
retry_count = 0;
- rc = ssh_userauth_kbdint(sess, nullptr, nullptr);
+ rc = ssh_userauth_kbdint(sess, NULL, NULL);
for (;;) {
if (rc == SSH_AUTH_SUCCESS) {
ok = true;
@@ -103,9 +95,9 @@ int main(int argc, char** argv)
retry_count += 1;
if (retry_count >= 5)
break;
- //ex_sleep_ms(500);
- Sleep(500);
- rc = ssh_userauth_kbdint(sess, nullptr, nullptr);
+ ex_sleep_ms(500);
+ // Sleep(500);
+ rc = ssh_userauth_kbdint(sess, NULL, NULL);
continue;
}
@@ -114,7 +106,7 @@ int main(int argc, char** argv)
int nprompts = ssh_userauth_kbdint_getnprompts(sess);
if (0 == nprompts) {
- rc = ssh_userauth_kbdint(sess, nullptr, nullptr);
+ rc = ssh_userauth_kbdint(sess, NULL, NULL);
continue;
}
@@ -131,21 +123,22 @@ int main(int argc, char** argv)
}
}
- rc = ssh_userauth_kbdint(sess, nullptr, nullptr);
+ rc = ssh_userauth_kbdint(sess, NULL, NULL);
}
}
// and then try password login mode if server allow.
if (!ok && (auth_methods & SSH_AUTH_METHOD_PASSWORD) == SSH_AUTH_METHOD_PASSWORD) {
retry_count = 0;
- rc = ssh_userauth_password(sess, nullptr, password);
+ rc = ssh_userauth_password(sess, NULL, password);
for (;;) {
if (rc == SSH_AUTH_AGAIN) {
retry_count += 1;
if (retry_count >= 3)
break;
- Sleep(100);
- rc = ssh_userauth_password(sess, nullptr, password);
+ ex_sleep_ms(100);
+ // Sleep(100);
+ rc = ssh_userauth_password(sess, NULL, password);
continue;
}
if (rc == SSH_AUTH_SUCCESS) {
diff --git a/server/tp_core/testssh/testssh.vcxproj b/server/tp_core/testssh/testssh.vcxproj
index 7e764b2..fb14cbc 100644
--- a/server/tp_core/testssh/testssh.vcxproj
+++ b/server/tp_core/testssh/testssh.vcxproj
@@ -73,7 +73,7 @@
true
WIN32;NDEBUG;_CONSOLE;LIBSSH_STATIC;%(PreprocessorDefinitions)
true
- ..\..\..\..\external\libssh\include;C:\Program Files (x86)\Visual Leak Detector\include;%(AdditionalIncludeDirectories)
+ ..\..\..\external\libssh\include;C:\Program Files (x86)\Visual Leak Detector\include;%(AdditionalIncludeDirectories)
MultiThreaded
@@ -81,7 +81,7 @@
true
true
true
- ..\..\..\..\external\libssh\build\src\static;..\..\..\..\external\openssl\out32;C:\Program Files (x86)\Visual Leak Detector\lib\Win32;%(AdditionalLibraryDirectories)
+ ..\..\..\external\libssh\build\src\static;..\..\..\external\openssl\out32;C:\Program Files (x86)\Visual Leak Detector\lib\Win32;%(AdditionalLibraryDirectories)
diff --git a/server/www/packages/packages-darwin/x64/psutil/__init__.py b/server/www/packages/packages-darwin/x64/psutil/__init__.py
index e129965..b400ec8 100644
--- a/server/www/packages/packages-darwin/x64/psutil/__init__.py
+++ b/server/www/packages/packages-darwin/x64/psutil/__init__.py
@@ -17,7 +17,7 @@ sensors) in Python. Supported platforms:
- Sun Solaris
- AIX
-Works with Python versions from 2.6 to 3.X.
+Works with Python versions from 2.6 to 3.4+.
"""
from __future__ import division
@@ -31,8 +31,8 @@ import os
import signal
import subprocess
import sys
+import threading
import time
-import traceback
try:
import pwd
except ImportError:
@@ -87,12 +87,6 @@ from ._common import POSIX # NOQA
from ._common import SUNOS
from ._common import WINDOWS
-from ._exceptions import AccessDenied
-from ._exceptions import Error
-from ._exceptions import NoSuchProcess
-from ._exceptions import TimeoutExpired
-from ._exceptions import ZombieProcess
-
if LINUX:
# This is public API and it will be retrieved from _pslinux.py
# via sys.modules.
@@ -152,6 +146,10 @@ elif WINDOWS:
from ._psutil_windows import NORMAL_PRIORITY_CLASS # NOQA
from ._psutil_windows import REALTIME_PRIORITY_CLASS # NOQA
from ._pswindows import CONN_DELETE_TCB # NOQA
+ from ._pswindows import IOPRIO_VERYLOW # NOQA
+ from ._pswindows import IOPRIO_LOW # NOQA
+ from ._pswindows import IOPRIO_NORMAL # NOQA
+ from ._pswindows import IOPRIO_HIGH # NOQA
elif MACOS:
from . import _psosx as _psplatform
@@ -212,23 +210,26 @@ __all__ = [
"pid_exists", "pids", "process_iter", "wait_procs", # proc
"virtual_memory", "swap_memory", # memory
"cpu_times", "cpu_percent", "cpu_times_percent", "cpu_count", # cpu
- "cpu_stats", # "cpu_freq",
+ "cpu_stats", # "cpu_freq", "getloadavg"
"net_io_counters", "net_connections", "net_if_addrs", # network
"net_if_stats",
"disk_io_counters", "disk_partitions", "disk_usage", # disk
# "sensors_temperatures", "sensors_battery", "sensors_fans" # sensors
"users", "boot_time", # others
]
+
+
__all__.extend(_psplatform.__extra__all__)
__author__ = "Giampaolo Rodola'"
-__version__ = "5.4.7"
+__version__ = "5.6.3"
version_info = tuple([int(num) for num in __version__.split('.')])
+
+_timer = getattr(time, 'monotonic', time.time)
AF_LINK = _psplatform.AF_LINK
POWER_TIME_UNLIMITED = _common.POWER_TIME_UNLIMITED
POWER_TIME_UNKNOWN = _common.POWER_TIME_UNKNOWN
_TOTAL_PHYMEM = None
-_timer = getattr(time, 'monotonic', time.time)
-
+_LOWEST_PID = None
# Sanity check in case the user messed up with psutil installation
# or did something weird with sys.path. In this case we might end
@@ -252,6 +253,112 @@ if (int(__version__.replace('.', '')) !=
raise ImportError(msg)
+# =====================================================================
+# --- Exceptions
+# =====================================================================
+
+
+class Error(Exception):
+ """Base exception class. All other psutil exceptions inherit
+ from this one.
+ """
+
+ def __init__(self, msg=""):
+ Exception.__init__(self, msg)
+ self.msg = msg
+
+ def __repr__(self):
+ ret = "psutil.%s %s" % (self.__class__.__name__, self.msg)
+ return ret.strip()
+
+ __str__ = __repr__
+
+
+class NoSuchProcess(Error):
+ """Exception raised when a process with a certain PID doesn't
+ or no longer exists.
+ """
+
+ def __init__(self, pid, name=None, msg=None):
+ Error.__init__(self, msg)
+ self.pid = pid
+ self.name = name
+ self.msg = msg
+ if msg is None:
+ if name:
+ details = "(pid=%s, name=%s)" % (self.pid, repr(self.name))
+ else:
+ details = "(pid=%s)" % self.pid
+ self.msg = "process no longer exists " + details
+
+
+class ZombieProcess(NoSuchProcess):
+ """Exception raised when querying a zombie process. This is
+ raised on macOS, BSD and Solaris only, and not always: depending
+ on the query the OS may be able to succeed anyway.
+ On Linux all zombie processes are querable (hence this is never
+ raised). Windows doesn't have zombie processes.
+ """
+
+ def __init__(self, pid, name=None, ppid=None, msg=None):
+ NoSuchProcess.__init__(self, msg)
+ self.pid = pid
+ self.ppid = ppid
+ self.name = name
+ self.msg = msg
+ if msg is None:
+ args = ["pid=%s" % pid]
+ if name:
+ args.append("name=%s" % repr(self.name))
+ if ppid:
+ args.append("ppid=%s" % self.ppid)
+ details = "(%s)" % ", ".join(args)
+ self.msg = "process still exists but it's a zombie " + details
+
+
+class AccessDenied(Error):
+ """Exception raised when permission to perform an action is denied."""
+
+ def __init__(self, pid=None, name=None, msg=None):
+ Error.__init__(self, msg)
+ self.pid = pid
+ self.name = name
+ self.msg = msg
+ if msg is None:
+ if (pid is not None) and (name is not None):
+ self.msg = "(pid=%s, name=%s)" % (pid, repr(name))
+ elif (pid is not None):
+ self.msg = "(pid=%s)" % self.pid
+ else:
+ self.msg = ""
+
+
+class TimeoutExpired(Error):
+ """Raised on Process.wait(timeout) if timeout expires and process
+ is still alive.
+ """
+
+ def __init__(self, seconds, pid=None, name=None):
+ Error.__init__(self, "timeout after %s seconds" % seconds)
+ self.seconds = seconds
+ self.pid = pid
+ self.name = name
+ if (pid is not None) and (name is not None):
+ self.msg += " (pid=%s, name=%s)" % (pid, repr(name))
+ elif (pid is not None):
+ self.msg += " (pid=%s)" % self.pid
+
+
+# Push exception classes into platform specific module namespace.
+_psplatform.NoSuchProcess = NoSuchProcess
+_psplatform.ZombieProcess = ZombieProcess
+_psplatform.AccessDenied = AccessDenied
+_psplatform.TimeoutExpired = TimeoutExpired
+if POSIX:
+ from . import _psposix
+ _psposix.TimeoutExpired = TimeoutExpired
+
+
# =====================================================================
# --- Utils
# =====================================================================
@@ -353,7 +460,7 @@ class Process(object):
self._create_time = None
self._gone = False
self._hash = None
- self._oneshot_inctx = False
+ self._lock = threading.RLock()
# used for caching on Windows only (on POSIX ppid may change)
self._ppid = None
# platform-specific modules define an _psplatform.Process
@@ -457,40 +564,45 @@ class Process(object):
...
>>>
"""
- if self._oneshot_inctx:
- # NOOP: this covers the use case where the user enters the
- # context twice. Since as_dict() internally uses oneshot()
- # I expect that the code below will be a pretty common
- # "mistake" that the user will make, so let's guard
- # against that:
- #
- # >>> with p.oneshot():
- # ... p.as_dict()
- # ...
- yield
- else:
- self._oneshot_inctx = True
- try:
- # cached in case cpu_percent() is used
- self.cpu_times.cache_activate()
- # cached in case memory_percent() is used
- self.memory_info.cache_activate()
- # cached in case parent() is used
- self.ppid.cache_activate()
- # cached in case username() is used
- if POSIX:
- self.uids.cache_activate()
- # specific implementation cache
- self._proc.oneshot_enter()
+ with self._lock:
+ if hasattr(self, "_cache"):
+ # NOOP: this covers the use case where the user enters the
+ # context twice:
+ #
+ # >>> with p.oneshot():
+ # ... with p.oneshot():
+ # ...
+ #
+ # Also, since as_dict() internally uses oneshot()
+ # I expect that the code below will be a pretty common
+ # "mistake" that the user will make, so let's guard
+ # against that:
+ #
+ # >>> with p.oneshot():
+ # ... p.as_dict()
+ # ...
yield
- finally:
- self.cpu_times.cache_deactivate()
- self.memory_info.cache_deactivate()
- self.ppid.cache_deactivate()
- if POSIX:
- self.uids.cache_deactivate()
- self._proc.oneshot_exit()
- self._oneshot_inctx = False
+ else:
+ try:
+ # cached in case cpu_percent() is used
+ self.cpu_times.cache_activate(self)
+ # cached in case memory_percent() is used
+ self.memory_info.cache_activate(self)
+ # cached in case parent() is used
+ self.ppid.cache_activate(self)
+ # cached in case username() is used
+ if POSIX:
+ self.uids.cache_activate(self)
+ # specific implementation cache
+ self._proc.oneshot_enter()
+ yield
+ finally:
+ self.cpu_times.cache_deactivate(self)
+ self.memory_info.cache_deactivate(self)
+ self.ppid.cache_deactivate(self)
+ if POSIX:
+ self.uids.cache_deactivate(self)
+ self._proc.oneshot_exit()
def as_dict(self, attrs=None, ad_value=None):
"""Utility method returning process information as a
@@ -541,6 +653,9 @@ class Process(object):
checking whether PID has been reused.
If no parent is known return None.
"""
+ lowest_pid = _LOWEST_PID if _LOWEST_PID is not None else pids()[0]
+ if self.pid == lowest_pid:
+ return None
ppid = self.ppid()
if ppid is not None:
ctime = self.create_time()
@@ -552,6 +667,17 @@ class Process(object):
except NoSuchProcess:
pass
+ def parents(self):
+ """Return the parents of this process as a list of Process
+ instances. If no parents are known return an empty list.
+ """
+ parents = []
+ proc = self.parent()
+ while proc is not None:
+ parents.append(proc)
+ proc = proc.parent()
+ return parents
+
def is_running(self):
"""Return whether this process is running.
It also checks if PID has been reused by another process in
@@ -800,9 +926,6 @@ class Process(object):
(and set).
(Windows, Linux and BSD only).
"""
- # Automatically remove duplicates both on get and
- # set (for get it's not really necessary, it's
- # just for extra safety).
if cpus is None:
return list(set(self._proc.cpu_affinity_get()))
else:
@@ -826,7 +949,7 @@ class Process(object):
"""
return self._proc.cpu_num()
- # Linux, macOS and Windows only
+ # Linux, macOS, Windows, Solaris, AIX
if hasattr(_psplatform.Process, "environ"):
def environ(self):
@@ -1096,7 +1219,6 @@ class Process(object):
return (value / float(total_phymem)) * 100
if hasattr(_psplatform.Process, "memory_maps"):
- # Available everywhere except OpenBSD and NetBSD.
def memory_maps(self, grouped=True):
"""Return process' mapped memory regions as a list of namedtuples
whose fields are variable depending on the platform.
@@ -1299,7 +1421,7 @@ class Popen(Process):
http://bugs.python.org/issue6973.
For a complete documentation refer to:
- http://docs.python.org/library/subprocess.html
+ http://docs.python.org/3/library/subprocess.html
"""
def __init__(self, *args, **kwargs):
@@ -1355,7 +1477,7 @@ class Popen(Process):
_as_dict_attrnames = set(
[x for x in dir(Process) if not x.startswith('_') and x not in
['send_signal', 'suspend', 'resume', 'terminate', 'kill', 'wait',
- 'is_running', 'as_dict', 'parent', 'children', 'rlimit',
+ 'is_running', 'as_dict', 'parent', 'parents', 'children', 'rlimit',
'memory_info_ex', 'oneshot']])
@@ -1366,7 +1488,10 @@ _as_dict_attrnames = set(
def pids():
"""Return a list of current running PIDs."""
- return _psplatform.pids()
+ global _LOWEST_PID
+ ret = sorted(_psplatform.pids())
+ _LOWEST_PID = ret[0]
+ return ret
def pid_exists(pid):
@@ -1388,6 +1513,7 @@ def pid_exists(pid):
_pmap = {}
+_lock = threading.Lock()
def process_iter(attrs=None, ad_value=None):
@@ -1415,21 +1541,26 @@ def process_iter(attrs=None, ad_value=None):
proc = Process(pid)
if attrs is not None:
proc.info = proc.as_dict(attrs=attrs, ad_value=ad_value)
- _pmap[proc.pid] = proc
+ with _lock:
+ _pmap[proc.pid] = proc
return proc
def remove(pid):
- _pmap.pop(pid, None)
+ with _lock:
+ _pmap.pop(pid, None)
a = set(pids())
b = set(_pmap.keys())
new_pids = a - b
gone_pids = b - a
-
for pid in gone_pids:
remove(pid)
- for pid, proc in sorted(list(_pmap.items()) +
- list(dict.fromkeys(new_pids).items())):
+
+ with _lock:
+ ls = sorted(list(_pmap.items()) +
+ list(dict.fromkeys(new_pids).items()))
+
+ for pid, proc in ls:
try:
if proc is None: # new process
yield add(pid)
@@ -1609,14 +1740,12 @@ try:
except Exception:
# Don't want to crash at import time.
_last_cpu_times = None
- traceback.print_exc()
try:
_last_per_cpu_times = cpu_times(percpu=True)
except Exception:
# Don't want to crash at import time.
_last_per_cpu_times = None
- traceback.print_exc()
def _cpu_tot_time(times):
@@ -1864,18 +1993,41 @@ if hasattr(_psplatform, "cpu_freq"):
return ret[0]
else:
currs, mins, maxs = 0.0, 0.0, 0.0
+ set_none = False
for cpu in ret:
currs += cpu.current
+ # On Linux if /proc/cpuinfo is used min/max are set
+ # to None.
+ if LINUX and cpu.min is None:
+ set_none = True
+ continue
mins += cpu.min
maxs += cpu.max
+
current = currs / num_cpus
- min_ = mins / num_cpus
- max_ = maxs / num_cpus
+
+ if set_none:
+ min_ = max_ = None
+ else:
+ min_ = mins / num_cpus
+ max_ = maxs / num_cpus
+
return _common.scpufreq(current, min_, max_)
__all__.append("cpu_freq")
+if hasattr(os, "getloadavg") or hasattr(_psplatform, "getloadavg"):
+ # Perform this hasattr check once on import time to either use the
+ # platform based code or proxy straight from the os module.
+ if hasattr(os, "getloadavg"):
+ getloadavg = os.getloadavg
+ else:
+ getloadavg = _psplatform.getloadavg
+
+ __all__.append("getloadavg")
+
+
# =====================================================================
# --- system memory related functions
# =====================================================================
@@ -1901,7 +2053,7 @@ def virtual_memory():
- used:
memory used, calculated differently depending on the platform and
designed for informational purposes only:
- macOS: active + inactive + wired
+ macOS: active + wired
BSD: active + wired + cached
Linux: total - free
@@ -2297,19 +2449,16 @@ if WINDOWS:
def test(): # pragma: no cover
- """List info of all currently running processes emulating ps aux
- output.
- """
+ from ._common import bytes2human
+ from ._compat import get_terminal_size
+
today_day = datetime.date.today()
- templ = "%-10s %5s %4s %7s %7s %-13s %5s %7s %s"
- attrs = ['pid', 'memory_percent', 'name', 'cpu_times', 'create_time',
- 'memory_info']
- if POSIX:
- attrs.append('uids')
- attrs.append('terminal')
- print(templ % ("USER", "PID", "%MEM", "VSZ", "RSS", "TTY", "START", "TIME",
- "COMMAND"))
- for p in process_iter(attrs=attrs, ad_value=''):
+ templ = "%-10s %5s %5s %7s %7s %5s %6s %6s %6s %s"
+ attrs = ['pid', 'memory_percent', 'name', 'cmdline', 'cpu_times',
+ 'create_time', 'memory_info', 'status', 'nice', 'username']
+ print(templ % ("USER", "PID", "%MEM", "VSZ", "RSS", "NICE",
+ "STATUS", "START", "TIME", "CMDLINE"))
+ for p in process_iter(attrs, ad_value=None):
if p.info['create_time']:
ctime = datetime.datetime.fromtimestamp(p.info['create_time'])
if ctime.date() == today_day:
@@ -2318,30 +2467,46 @@ def test(): # pragma: no cover
ctime = ctime.strftime("%b%d")
else:
ctime = ''
- cputime = time.strftime("%M:%S",
- time.localtime(sum(p.info['cpu_times'])))
- try:
- user = p.username()
- except Error:
- user = ''
- if WINDOWS and '\\' in user:
+ if p.info['cpu_times']:
+ cputime = time.strftime("%M:%S",
+ time.localtime(sum(p.info['cpu_times'])))
+ else:
+ cputime = ''
+
+ user = p.info['username'] or ''
+ if not user and POSIX:
+ try:
+ user = p.uids()[0]
+ except Error:
+ pass
+ if user and WINDOWS and '\\' in user:
user = user.split('\\')[1]
- vms = p.info['memory_info'] and \
- int(p.info['memory_info'].vms / 1024) or '?'
- rss = p.info['memory_info'] and \
- int(p.info['memory_info'].rss / 1024) or '?'
- memp = p.info['memory_percent'] and \
- round(p.info['memory_percent'], 1) or '?'
- print(templ % (
+ user = user[:9]
+ vms = bytes2human(p.info['memory_info'].vms) if \
+ p.info['memory_info'] is not None else ''
+ rss = bytes2human(p.info['memory_info'].rss) if \
+ p.info['memory_info'] is not None else ''
+ memp = round(p.info['memory_percent'], 1) if \
+ p.info['memory_percent'] is not None else ''
+ nice = int(p.info['nice']) if p.info['nice'] else ''
+ if p.info['cmdline']:
+ cmdline = ' '.join(p.info['cmdline'])
+ else:
+ cmdline = p.info['name']
+ status = p.info['status'][:5] if p.info['status'] else ''
+
+ line = templ % (
user[:10],
p.info['pid'],
memp,
vms,
rss,
- p.info.get('terminal', '') or '?',
+ nice,
+ status,
ctime,
cputime,
- p.info['name'].strip() or '?'))
+ cmdline)
+ print(line[:get_terminal_size()[0]])
del memoize, memoize_when_activated, division, deprecated_method
diff --git a/server/www/packages/packages-darwin/x64/psutil/_common.py b/server/www/packages/packages-darwin/x64/psutil/_common.py
index 2cc3939..e3b4541 100644
--- a/server/www/packages/packages-darwin/x64/psutil/_common.py
+++ b/server/www/packages/packages-darwin/x64/psutil/_common.py
@@ -64,6 +64,7 @@ __all__ = [
'conn_tmap', 'deprecated_method', 'isfile_strict', 'memoize',
'parse_environ_block', 'path_exists_strict', 'usage_percent',
'supports_ipv6', 'sockfam_to_enum', 'socktype_to_enum', "wrap_numbers",
+ 'bytes2human',
]
@@ -327,7 +328,7 @@ def memoize_when_activated(fun):
1
>>>
>>> # activated
- >>> foo.cache_activate()
+ >>> foo.cache_activate(self)
>>> foo()
1
>>> foo()
@@ -336,26 +337,30 @@ def memoize_when_activated(fun):
"""
@functools.wraps(fun)
def wrapper(self):
- if not wrapper.cache_activated:
+ try:
+ # case 1: we previously entered oneshot() ctx
+ ret = self._cache[fun]
+ except AttributeError:
+ # case 2: we never entered oneshot() ctx
return fun(self)
- else:
- try:
- ret = cache[fun]
- except KeyError:
- ret = cache[fun] = fun(self)
- return ret
+ except KeyError:
+ # case 3: we entered oneshot() ctx but there's no cache
+ # for this entry yet
+ ret = self._cache[fun] = fun(self)
+ return ret
- def cache_activate():
- """Activate cache."""
- wrapper.cache_activated = True
+ def cache_activate(proc):
+ """Activate cache. Expects a Process instance. Cache will be
+ stored as a "_cache" instance attribute."""
+ proc._cache = {}
- def cache_deactivate():
+ def cache_deactivate(proc):
"""Deactivate and clear cache."""
- wrapper.cache_activated = False
- cache.clear()
+ try:
+ del proc._cache
+ except AttributeError:
+ pass
- cache = {}
- wrapper.cache_activated = False
wrapper.cache_activate = cache_activate
wrapper.cache_deactivate = cache_deactivate
return wrapper
@@ -471,7 +476,7 @@ def deprecated_method(replacement):
@functools.wraps(fun)
def inner(self, *args, **kwargs):
- warnings.warn(msg, category=FutureWarning, stacklevel=2)
+ warnings.warn(msg, category=DeprecationWarning, stacklevel=2)
return getattr(self, replacement)(*args, **kwargs)
return inner
return outer
@@ -576,3 +581,54 @@ def wrap_numbers(input_dict, name):
_wn = _WrapNumbers()
wrap_numbers.cache_clear = _wn.cache_clear
wrap_numbers.cache_info = _wn.cache_info
+
+
+def open_binary(fname, **kwargs):
+ return open(fname, "rb", **kwargs)
+
+
+def open_text(fname, **kwargs):
+ """On Python 3 opens a file in text mode by using fs encoding and
+ a proper en/decoding errors handler.
+ On Python 2 this is just an alias for open(name, 'rt').
+ """
+ if PY3:
+ # See:
+ # https://github.com/giampaolo/psutil/issues/675
+ # https://github.com/giampaolo/psutil/pull/733
+ kwargs.setdefault('encoding', ENCODING)
+ kwargs.setdefault('errors', ENCODING_ERRS)
+ return open(fname, "rt", **kwargs)
+
+
+def bytes2human(n, format="%(value).1f%(symbol)s"):
+ """Used by various scripts. See:
+ http://goo.gl/zeJZl
+
+ >>> bytes2human(10000)
+ '9.8K'
+ >>> bytes2human(100001221)
+ '95.4M'
+ """
+ symbols = ('B', 'K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y')
+ prefix = {}
+ for i, s in enumerate(symbols[1:]):
+ prefix[s] = 1 << (i + 1) * 10
+ for symbol in reversed(symbols[1:]):
+ if n >= prefix[symbol]:
+ value = float(n) / prefix[symbol]
+ return format % locals()
+ return format % dict(symbol=symbols[0], value=n)
+
+
+def get_procfs_path():
+ """Return updated psutil.PROCFS_PATH constant."""
+ return sys.modules['psutil'].PROCFS_PATH
+
+
+if PY3:
+ def decode(s):
+ return s.decode(encoding=ENCODING, errors=ENCODING_ERRS)
+else:
+ def decode(s):
+ return s
diff --git a/server/www/packages/packages-darwin/x64/psutil/_compat.py b/server/www/packages/packages-darwin/x64/psutil/_compat.py
index 08aefe4..c772f61 100644
--- a/server/www/packages/packages-darwin/x64/psutil/_compat.py
+++ b/server/www/packages/packages-darwin/x64/psutil/_compat.py
@@ -10,7 +10,7 @@ import os
import sys
__all__ = ["PY3", "long", "xrange", "unicode", "basestring", "u", "b",
- "lru_cache", "which"]
+ "lru_cache", "which", "get_terminal_size"]
PY3 = sys.version_info[0] == 3
@@ -239,3 +239,24 @@ except ImportError:
if _access_check(name, mode):
return name
return None
+
+
+# python 3.3
+try:
+ from shutil import get_terminal_size
+except ImportError:
+ def get_terminal_size(fallback=(80, 24)):
+ try:
+ import fcntl
+ import termios
+ import struct
+ except ImportError:
+ return fallback
+ else:
+ try:
+ # This should work on Linux.
+ res = struct.unpack(
+ 'hh', fcntl.ioctl(1, termios.TIOCGWINSZ, '1234'))
+ return (res[1], res[0])
+ except Exception:
+ return fallback
diff --git a/server/www/packages/packages-darwin/x64/psutil/_exceptions.py b/server/www/packages/packages-darwin/x64/psutil/_exceptions.py
deleted file mode 100644
index 6dbbd28..0000000
--- a/server/www/packages/packages-darwin/x64/psutil/_exceptions.py
+++ /dev/null
@@ -1,94 +0,0 @@
-# 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.
-
-
-class Error(Exception):
- """Base exception class. All other psutil exceptions inherit
- from this one.
- """
-
- def __init__(self, msg=""):
- Exception.__init__(self, msg)
- self.msg = msg
-
- def __repr__(self):
- ret = "psutil.%s %s" % (self.__class__.__name__, self.msg)
- return ret.strip()
-
- __str__ = __repr__
-
-
-class NoSuchProcess(Error):
- """Exception raised when a process with a certain PID doesn't
- or no longer exists.
- """
-
- def __init__(self, pid, name=None, msg=None):
- Error.__init__(self, msg)
- self.pid = pid
- self.name = name
- self.msg = msg
- if msg is None:
- if name:
- details = "(pid=%s, name=%s)" % (self.pid, repr(self.name))
- else:
- details = "(pid=%s)" % self.pid
- self.msg = "process no longer exists " + details
-
-
-class ZombieProcess(NoSuchProcess):
- """Exception raised when querying a zombie process. This is
- raised on macOS, BSD and Solaris only, and not always: depending
- on the query the OS may be able to succeed anyway.
- On Linux all zombie processes are querable (hence this is never
- raised). Windows doesn't have zombie processes.
- """
-
- def __init__(self, pid, name=None, ppid=None, msg=None):
- NoSuchProcess.__init__(self, msg)
- self.pid = pid
- self.ppid = ppid
- self.name = name
- self.msg = msg
- if msg is None:
- args = ["pid=%s" % pid]
- if name:
- args.append("name=%s" % repr(self.name))
- if ppid:
- args.append("ppid=%s" % self.ppid)
- details = "(%s)" % ", ".join(args)
- self.msg = "process still exists but it's a zombie " + details
-
-
-class AccessDenied(Error):
- """Exception raised when permission to perform an action is denied."""
-
- def __init__(self, pid=None, name=None, msg=None):
- Error.__init__(self, msg)
- self.pid = pid
- self.name = name
- self.msg = msg
- if msg is None:
- if (pid is not None) and (name is not None):
- self.msg = "(pid=%s, name=%s)" % (pid, repr(name))
- elif (pid is not None):
- self.msg = "(pid=%s)" % self.pid
- else:
- self.msg = ""
-
-
-class TimeoutExpired(Error):
- """Raised on Process.wait(timeout) if timeout expires and process
- is still alive.
- """
-
- def __init__(self, seconds, pid=None, name=None):
- Error.__init__(self, "timeout after %s seconds" % seconds)
- self.seconds = seconds
- self.pid = pid
- self.name = name
- if (pid is not None) and (name is not None):
- self.msg += " (pid=%s, name=%s)" % (pid, repr(name))
- elif (pid is not None):
- self.msg += " (pid=%s)" % self.pid
diff --git a/server/www/packages/packages-darwin/x64/psutil/_psaix.py b/server/www/packages/packages-darwin/x64/psutil/_psaix.py
index 7ba212d..b24325d 100644
--- a/server/www/packages/packages-darwin/x64/psutil/_psaix.py
+++ b/server/www/packages/packages-darwin/x64/psutil/_psaix.py
@@ -7,6 +7,7 @@
"""AIX platform implementation."""
import errno
+import functools
import glob
import os
import re
@@ -20,6 +21,7 @@ from . import _psposix
from . import _psutil_aix as cext
from . import _psutil_posix as cext_posix
from ._common import AF_INET6
+from ._common import get_procfs_path
from ._common import memoize_when_activated
from ._common import NIC_DUPLEX_FULL
from ._common import NIC_DUPLEX_HALF
@@ -28,9 +30,6 @@ from ._common import sockfam_to_enum
from ._common import socktype_to_enum
from ._common import usage_percent
from ._compat import PY3
-from ._exceptions import AccessDenied
-from ._exceptions import NoSuchProcess
-from ._exceptions import ZombieProcess
__extra__all__ = ["PROCFS_PATH"]
@@ -42,6 +41,8 @@ __extra__all__ = ["PROCFS_PATH"]
HAS_THREADS = hasattr(cext, "proc_threads")
+HAS_NET_IO_COUNTERS = hasattr(cext, "net_io_counters")
+HAS_PROC_IO_COUNTERS = hasattr(cext, "proc_io_counters")
PAGE_SIZE = os.sysconf('SC_PAGE_SIZE')
AF_LINK = cext_posix.AF_LINK
@@ -79,6 +80,13 @@ proc_info_map = dict(
status=6,
ttynr=7)
+# These objects get set on "import psutil" from the __init__.py
+# file, see: https://github.com/giampaolo/psutil/issues/1402
+NoSuchProcess = None
+ZombieProcess = None
+AccessDenied = None
+TimeoutExpired = None
+
# =====================================================================
# --- named tuples
@@ -93,21 +101,6 @@ pfullmem = pmem
scputimes = namedtuple('scputimes', ['user', 'system', 'idle', 'iowait'])
# psutil.virtual_memory()
svmem = namedtuple('svmem', ['total', 'available', 'percent', 'used', 'free'])
-# psutil.Process.memory_maps(grouped=True)
-pmmap_grouped = namedtuple('pmmap_grouped', ['path', 'rss', 'anon', 'locked'])
-# psutil.Process.memory_maps(grouped=False)
-pmmap_ext = namedtuple(
- 'pmmap_ext', 'addr perms ' + ' '.join(pmmap_grouped._fields))
-
-
-# =====================================================================
-# --- utils
-# =====================================================================
-
-
-def get_procfs_path():
- """Return updated psutil.PROCFS_PATH constant."""
- return sys.modules['psutil'].PROCFS_PATH
# =====================================================================
@@ -212,7 +205,9 @@ def disk_partitions(all=False):
net_if_addrs = cext_posix.net_if_addrs
-net_io_counters = cext.net_io_counters
+
+if HAS_NET_IO_COUNTERS:
+ net_io_counters = cext.net_io_counters
def net_connections(kind, _pid=-1):
@@ -328,7 +323,7 @@ def wrap_exceptions(fun):
"""Call callable into a try/except clause and translate ENOENT,
EACCES and EPERM in NoSuchProcess or AccessDenied exceptions.
"""
-
+ @functools.wraps(fun)
def wrapper(self, *args, **kwargs):
try:
return fun(self, *args, **kwargs)
@@ -354,7 +349,7 @@ def wrap_exceptions(fun):
class Process(object):
"""Wrapper class around underlying C implementation."""
- __slots__ = ["pid", "_name", "_ppid", "_procfs_path"]
+ __slots__ = ["pid", "_name", "_ppid", "_procfs_path", "_cache"]
def __init__(self, pid):
self.pid = pid
@@ -363,23 +358,19 @@ class Process(object):
self._procfs_path = get_procfs_path()
def oneshot_enter(self):
- self._proc_name_and_args.cache_activate()
- self._proc_basic_info.cache_activate()
- self._proc_cred.cache_activate()
+ self._proc_basic_info.cache_activate(self)
+ self._proc_cred.cache_activate(self)
def oneshot_exit(self):
- self._proc_name_and_args.cache_deactivate()
- self._proc_basic_info.cache_deactivate()
- self._proc_cred.cache_deactivate()
-
- @memoize_when_activated
- def _proc_name_and_args(self):
- return cext.proc_name_and_args(self.pid, self._procfs_path)
+ self._proc_basic_info.cache_deactivate(self)
+ self._proc_cred.cache_deactivate(self)
+ @wrap_exceptions
@memoize_when_activated
def _proc_basic_info(self):
return cext.proc_basic_info(self.pid, self._procfs_path)
+ @wrap_exceptions
@memoize_when_activated
def _proc_cred(self):
return cext.proc_cred(self.pid, self._procfs_path)
@@ -388,22 +379,25 @@ class Process(object):
def name(self):
if self.pid == 0:
return "swapper"
- # note: this is limited to 15 characters
- return self._proc_name_and_args()[0].rstrip("\x00")
+ # note: max 16 characters
+ return cext.proc_name(self.pid, self._procfs_path).rstrip("\x00")
@wrap_exceptions
def exe(self):
# there is no way to get executable path in AIX other than to guess,
# and guessing is more complex than what's in the wrapping class
- exe = self.cmdline()[0]
+ cmdline = self.cmdline()
+ if not cmdline:
+ return ''
+ exe = cmdline[0]
if os.path.sep in exe:
# relative or absolute path
if not os.path.isabs(exe):
# if cwd has changed, we're out of luck - this may be wrong!
exe = os.path.abspath(os.path.join(self.cwd(), exe))
if (os.path.isabs(exe) and
- os.path.isfile(exe) and
- os.access(exe, os.X_OK)):
+ os.path.isfile(exe) and
+ os.access(exe, os.X_OK)):
return exe
# not found, move to search in PATH using basename only
exe = os.path.basename(exe)
@@ -411,13 +405,17 @@ class Process(object):
for path in os.environ["PATH"].split(":"):
possible_exe = os.path.abspath(os.path.join(path, exe))
if (os.path.isfile(possible_exe) and
- os.access(possible_exe, os.X_OK)):
+ os.access(possible_exe, os.X_OK)):
return possible_exe
return ''
@wrap_exceptions
def cmdline(self):
- return self._proc_name_and_args()[1].split(' ')
+ return cext.proc_args(self.pid)
+
+ @wrap_exceptions
+ def environ(self):
+ return cext.proc_environ(self.pid)
@wrap_exceptions
def create_time(self):
@@ -561,14 +559,15 @@ class Process(object):
def wait(self, timeout=None):
return _psposix.wait_pid(self.pid, timeout, self._name)
- @wrap_exceptions
- def io_counters(self):
- try:
- rc, wc, rb, wb = cext.proc_io_counters(self.pid)
- except OSError:
- # if process is terminated, proc_io_counters returns OSError
- # instead of NSP
- if not pid_exists(self.pid):
- raise NoSuchProcess(self.pid, self._name)
- raise
- return _common.pio(rc, wc, rb, wb)
+ if HAS_PROC_IO_COUNTERS:
+ @wrap_exceptions
+ def io_counters(self):
+ try:
+ rc, wc, rb, wb = cext.proc_io_counters(self.pid)
+ except OSError:
+ # if process is terminated, proc_io_counters returns OSError
+ # instead of NSP
+ if not pid_exists(self.pid):
+ raise NoSuchProcess(self.pid, self._name)
+ raise
+ return _common.pio(rc, wc, rb, wb)
diff --git a/server/www/packages/packages-darwin/x64/psutil/_psbsd.py b/server/www/packages/packages-darwin/x64/psutil/_psbsd.py
index 7f4bcb6..3d9dfda 100644
--- a/server/www/packages/packages-darwin/x64/psutil/_psbsd.py
+++ b/server/www/packages/packages-darwin/x64/psutil/_psbsd.py
@@ -11,6 +11,7 @@ import os
import xml.etree.ElementTree as ET
from collections import namedtuple
from socket import AF_INET
+from collections import defaultdict
from . import _common
from . import _psposix
@@ -27,9 +28,6 @@ from ._common import sockfam_to_enum
from ._common import socktype_to_enum
from ._common import usage_percent
from ._compat import which
-from ._exceptions import AccessDenied
-from ._exceptions import NoSuchProcess
-from ._exceptions import ZombieProcess
__extra__all__ = []
@@ -103,6 +101,11 @@ else:
PAGESIZE = os.sysconf("SC_PAGE_SIZE")
AF_LINK = cext_posix.AF_LINK
+HAS_PER_CPU_TIMES = hasattr(cext, "per_cpu_times")
+HAS_PROC_NUM_THREADS = hasattr(cext, "proc_num_threads")
+HAS_PROC_OPEN_FILES = hasattr(cext, 'proc_open_files')
+HAS_PROC_NUM_FDS = hasattr(cext, 'proc_num_fds')
+
kinfo_proc_map = dict(
ppid=0,
status=1,
@@ -131,6 +134,13 @@ kinfo_proc_map = dict(
name=24,
)
+# These objects get set on "import psutil" from the __init__.py
+# file, see: https://github.com/giampaolo/psutil/issues/1402
+NoSuchProcess = None
+ZombieProcess = None
+AccessDenied = None
+TimeoutExpired = None
+
# =====================================================================
# --- named tuples
@@ -211,7 +221,7 @@ def cpu_times():
return scputimes(user, nice, system, idle, irq)
-if hasattr(cext, "per_cpu_times"):
+if HAS_PER_CPU_TIMES:
def per_cpu_times():
"""Return system CPU times as a namedtuple"""
ret = []
@@ -432,6 +442,47 @@ if FREEBSD:
secsleft = minsleft * 60
return _common.sbattery(percent, secsleft, power_plugged)
+ def sensors_temperatures():
+ "Return CPU cores temperatures if available, else an empty dict."
+ ret = defaultdict(list)
+ num_cpus = cpu_count_logical()
+ for cpu in range(num_cpus):
+ try:
+ current, high = cext.sensors_cpu_temperature(cpu)
+ if high <= 0:
+ high = None
+ name = "Core %s" % cpu
+ ret["coretemp"].append(
+ _common.shwtemp(name, current, high, high))
+ except NotImplementedError:
+ pass
+
+ return ret
+
+ def cpu_freq():
+ """Return frequency metrics for CPUs. As of Dec 2018 only
+ CPU 0 appears to be supported by FreeBSD and all other cores
+ match the frequency of CPU 0.
+ """
+ ret = []
+ num_cpus = cpu_count_logical()
+ for cpu in range(num_cpus):
+ try:
+ current, available_freq = cext.cpu_frequency(cpu)
+ except NotImplementedError:
+ continue
+ if available_freq:
+ try:
+ min_freq = int(available_freq.split(" ")[-1].split("/")[0])
+ except(IndexError, ValueError):
+ min_freq = None
+ try:
+ max_freq = int(available_freq.split(" ")[0].split("/")[0])
+ except(IndexError, ValueError):
+ max_freq = None
+ ret.append(_common.scpufreq(current, min_freq, max_freq))
+ return ret
+
# =====================================================================
# --- other system functions
@@ -547,13 +598,20 @@ def wrap_exceptions_procfs(inst):
class Process(object):
"""Wrapper class around underlying C implementation."""
- __slots__ = ["pid", "_name", "_ppid"]
+ __slots__ = ["pid", "_name", "_ppid", "_cache"]
def __init__(self, pid):
self.pid = pid
self._name = None
self._ppid = None
+ def _assert_alive(self):
+ """Raise NSP if the process disappeared on us."""
+ # For those C function who do not raise NSP, possibly returning
+ # incorrect or incomplete result.
+ cext.proc_name(self.pid)
+
+ @wrap_exceptions
@memoize_when_activated
def oneshot(self):
"""Retrieves multiple process info in one shot as a raw tuple."""
@@ -562,10 +620,10 @@ class Process(object):
return ret
def oneshot_enter(self):
- self.oneshot.cache_activate()
+ self.oneshot.cache_activate(self)
def oneshot_exit(self):
- self.oneshot.cache_deactivate()
+ self.oneshot.cache_deactivate(self)
@wrap_exceptions
def name(self):
@@ -678,7 +736,7 @@ class Process(object):
@wrap_exceptions
def num_threads(self):
- if hasattr(cext, "proc_num_threads"):
+ if HAS_PROC_NUM_THREADS:
# FreeBSD
return cext.proc_num_threads(self.pid)
else:
@@ -700,10 +758,7 @@ class Process(object):
ntuple = _common.pthread(thread_id, utime, stime)
retlist.append(ntuple)
if OPENBSD:
- # On OpenBSD the underlying C function does not raise NSP
- # in case the process is gone (and the returned list may
- # incomplete).
- self.name() # raise NSP if the process disappeared on us
+ self._assert_alive()
return retlist
@wrap_exceptions
@@ -733,10 +788,7 @@ class Process(object):
type = socktype_to_enum(type)
nt = _common.pconn(fd, fam, type, laddr, raddr, status)
ret.add(nt)
- # On NetBSD the underlying C function does not raise NSP
- # in case the process is gone (and the returned list may
- # incomplete).
- self.name() # raise NSP if the process disappeared on us
+ self._assert_alive()
return list(ret)
families, types = conn_tmap[kind]
@@ -755,10 +807,7 @@ class Process(object):
nt = _common.pconn(fd, fam, type, laddr, raddr, status)
ret.append(nt)
if OPENBSD:
- # On OpenBSD the underlying C function does not raise NSP
- # in case the process is gone (and the returned list may
- # incomplete).
- self.name() # raise NSP if the process disappeared on us
+ self._assert_alive()
return ret
@wrap_exceptions
@@ -798,7 +847,7 @@ class Process(object):
elif NETBSD:
with wrap_exceptions_procfs(self):
return os.readlink("/proc/%s/cwd" % self.pid)
- elif hasattr(cext, 'proc_open_files'):
+ elif HAS_PROC_OPEN_FILES:
# FreeBSD < 8 does not support functions based on
# kinfo_getfile() and kinfo_getvmmap()
return cext.proc_cwd(self.pid) or None
@@ -817,7 +866,7 @@ class Process(object):
# FreeBSD < 8 does not support functions based on kinfo_getfile()
# and kinfo_getvmmap()
- if hasattr(cext, 'proc_open_files'):
+ if HAS_PROC_OPEN_FILES:
@wrap_exceptions
def open_files(self):
"""Return files opened by process as a list of namedtuples."""
@@ -828,15 +877,13 @@ class Process(object):
# FreeBSD < 8 does not support functions based on kinfo_getfile()
# and kinfo_getvmmap()
- if hasattr(cext, 'proc_num_fds'):
+ if HAS_PROC_NUM_FDS:
@wrap_exceptions
def num_fds(self):
"""Return the number of file descriptors opened by this process."""
ret = cext.proc_num_fds(self.pid)
if NETBSD:
- # On NetBSD the underlying C function does not raise NSP
- # in case the process is gone.
- self.name() # raise NSP if the process disappeared on us
+ self._assert_alive()
return ret
else:
num_fds = _not_implemented
diff --git a/server/www/packages/packages-darwin/x64/psutil/_pslinux.py b/server/www/packages/packages-darwin/x64/psutil/_pslinux.py
index df624de..e4bc7d7 100644
--- a/server/www/packages/packages-darwin/x64/psutil/_pslinux.py
+++ b/server/www/packages/packages-darwin/x64/psutil/_pslinux.py
@@ -25,25 +25,23 @@ from . import _common
from . import _psposix
from . import _psutil_linux as cext
from . import _psutil_posix as cext_posix
-from ._common import ENCODING
-from ._common import ENCODING_ERRS
+from ._common import decode
+from ._common import get_procfs_path
from ._common import isfile_strict
from ._common import memoize
from ._common import memoize_when_activated
from ._common import NIC_DUPLEX_FULL
from ._common import NIC_DUPLEX_HALF
from ._common import NIC_DUPLEX_UNKNOWN
+from ._common import open_binary
+from ._common import open_text
from ._common import parse_environ_block
from ._common import path_exists_strict
from ._common import supports_ipv6
from ._common import usage_percent
from ._compat import b
from ._compat import basestring
-from ._compat import long
from ._compat import PY3
-from ._exceptions import AccessDenied
-from ._exceptions import NoSuchProcess
-from ._exceptions import ZombieProcess
if sys.version_info >= (3, 4):
import enum
@@ -71,6 +69,7 @@ __extra__all__ = [
POWER_SUPPLY_PATH = "/sys/class/power_supply"
HAS_SMAPS = os.path.exists('/proc/%s/smaps' % os.getpid())
HAS_PRLIMIT = hasattr(cext, "linux_prlimit")
+HAS_PROC_IO_PRIORITY = hasattr(cext, "proc_ioprio_get")
_DEFAULT = object()
# RLIMIT_* constants, not guaranteed to be present on all kernels
@@ -158,6 +157,13 @@ TCP_STATUSES = {
"0B": _common.CONN_CLOSING
}
+# These objects get set on "import psutil" from the __init__.py
+# file, see: https://github.com/giampaolo/psutil/issues/1402
+NoSuchProcess = None
+ZombieProcess = None
+AccessDenied = None
+TimeoutExpired = None
+
# =====================================================================
# --- named tuples
@@ -201,37 +207,6 @@ pio = namedtuple('pio', ['read_count', 'write_count',
# =====================================================================
-def open_binary(fname, **kwargs):
- return open(fname, "rb", **kwargs)
-
-
-def open_text(fname, **kwargs):
- """On Python 3 opens a file in text mode by using fs encoding and
- a proper en/decoding errors handler.
- On Python 2 this is just an alias for open(name, 'rt').
- """
- if PY3:
- # See:
- # https://github.com/giampaolo/psutil/issues/675
- # https://github.com/giampaolo/psutil/pull/733
- kwargs.setdefault('encoding', ENCODING)
- kwargs.setdefault('errors', ENCODING_ERRS)
- return open(fname, "rt", **kwargs)
-
-
-if PY3:
- def decode(s):
- return s.decode(encoding=ENCODING, errors=ENCODING_ERRS)
-else:
- def decode(s):
- return s
-
-
-def get_procfs_path():
- """Return updated psutil.PROCFS_PATH constant."""
- return sys.modules['psutil'].PROCFS_PATH
-
-
def readlink(path):
"""Wrapper around os.readlink()."""
assert isinstance(path, basestring), path
@@ -638,6 +613,17 @@ def cpu_count_logical():
def cpu_count_physical():
"""Return the number of physical cores in the system."""
+ # Method #1
+ core_ids = set()
+ for path in glob.glob(
+ "/sys/devices/system/cpu/cpu[0-9]*/topology/core_id"):
+ with open_binary(path) as f:
+ core_ids.add(int(f.read()))
+ result = len(core_ids)
+ if result != 0:
+ return result
+
+ # Method #2
mapping = {}
current_info = {}
with open_binary('%s/cpuinfo' % get_procfs_path()) as f:
@@ -657,8 +643,8 @@ def cpu_count_physical():
key, value = line.split(b'\t:', 1)
current_info[key] = int(value)
- # mimic os.cpu_count()
- return sum(mapping.values()) or None
+ result = sum(mapping.values())
+ return result or None # mimic os.cpu_count()
def cpu_stats():
@@ -682,30 +668,26 @@ def cpu_stats():
ctx_switches, interrupts, soft_interrupts, syscalls)
-if os.path.exists("/sys/devices/system/cpu/cpufreq") or \
+if os.path.exists("/sys/devices/system/cpu/cpufreq/policy0") or \
os.path.exists("/sys/devices/system/cpu/cpu0/cpufreq"):
def cpu_freq():
"""Return frequency metrics for all CPUs.
Contrarily to other OSes, Linux updates these values in
real-time.
"""
- # scaling_* files seem preferable to cpuinfo_*, see:
- # http://unix.stackexchange.com/a/87537/168884
- ret = []
- ls = glob.glob("/sys/devices/system/cpu/cpufreq/policy*")
- if ls:
- # Sort the list so that '10' comes after '2'. This should
- # ensure the CPU order is consistent with other CPU functions
- # having a 'percpu' argument and returning results for multiple
- # CPUs (cpu_times(), cpu_percent(), cpu_times_percent()).
- ls.sort(key=lambda x: int(os.path.basename(x)[6:]))
- else:
- # https://github.com/giampaolo/psutil/issues/981
- ls = glob.glob("/sys/devices/system/cpu/cpu[0-9]*/cpufreq")
- ls.sort(key=lambda x: int(re.search('[0-9]+', x).group(0)))
+ def get_path(num):
+ for p in ("/sys/devices/system/cpu/cpufreq/policy%s" % num,
+ "/sys/devices/system/cpu/cpu%s/cpufreq" % num):
+ if os.path.exists(p):
+ return p
- pjoin = os.path.join
- for path in ls:
+ ret = []
+ for n in range(cpu_count_logical()):
+ path = get_path(n)
+ if not path:
+ continue
+
+ pjoin = os.path.join
curr = cat(pjoin(path, "scaling_cur_freq"), fallback=None)
if curr is None:
# Likely an old RedHat, see:
@@ -720,6 +702,25 @@ if os.path.exists("/sys/devices/system/cpu/cpufreq") or \
ret.append(_common.scpufreq(curr, min_, max_))
return ret
+elif os.path.exists("/proc/cpuinfo"):
+ def cpu_freq():
+ """Alternate implementation using /proc/cpuinfo.
+ min and max frequencies are not available and are set to None.
+ """
+ ret = []
+ with open_binary('%s/cpuinfo' % get_procfs_path()) as f:
+ for line in f:
+ if line.lower().startswith(b'cpu mhz'):
+ key, value = line.split(b'\t:', 1)
+ ret.append(_common.scpufreq(float(value), 0., 0.))
+ return ret
+
+else:
+ def cpu_freq():
+ """Dummy implementation when none of the above files are present.
+ """
+ return []
+
# =====================================================================
# --- network
@@ -1062,6 +1063,8 @@ def disk_io_counters(perdisk=False):
# ...unless (Linux 2.6) the line refers to a partition instead
# of a disk, in which case the line has less fields (7):
# "3 1 hda1 8 8 8 8"
+ # 4.18+ has 4 fields added:
+ # "3 0 hda 8 8 8 8 8 8 8 8 8 8 8 0 0 0 0"
# See:
# https://www.kernel.org/doc/Documentation/iostats.txt
# https://www.kernel.org/doc/Documentation/ABI/testing/procfs-diskstats
@@ -1076,7 +1079,7 @@ def disk_io_counters(perdisk=False):
reads = int(fields[2])
(reads_merged, rbytes, rtime, writes, writes_merged,
wbytes, wtime, _, busy_time, _) = map(int, fields[4:14])
- elif flen == 14:
+ elif flen == 14 or flen == 18:
# Linux 2.6+, line referring to a disk
name = fields[2]
(reads, reads_merged, rbytes, rtime, writes, writes_merged,
@@ -1142,7 +1145,8 @@ def disk_io_counters(perdisk=False):
def disk_partitions(all=False):
"""Return mounted disk partitions as a list of namedtuples."""
fstypes = set()
- with open_text("%s/filesystems" % get_procfs_path()) as f:
+ procfs_path = get_procfs_path()
+ with open_text("%s/filesystems" % procfs_path) as f:
for line in f:
line = line.strip()
if not line.startswith("nodev"):
@@ -1153,8 +1157,14 @@ def disk_partitions(all=False):
if fstype == "zfs":
fstypes.add("zfs")
+ # See: https://github.com/giampaolo/psutil/issues/1307
+ if procfs_path == "/proc" and os.path.isfile('/etc/mtab'):
+ mounts_path = os.path.realpath("/etc/mtab")
+ else:
+ mounts_path = os.path.realpath("%s/self/mounts" % procfs_path)
+
retlist = []
- partitions = cext.disk_partitions()
+ partitions = cext.disk_partitions(mounts_path)
for partition in partitions:
device, mountpoint, fstype, opts = partition
if device == 'none':
@@ -1229,7 +1239,51 @@ def sensors_temperatures():
ret[unit_name].append((label, current, high, critical))
- return ret
+ # Indication that no sensors were detected in /sys/class/hwmon/
+ if not basenames:
+ basenames = glob.glob('/sys/class/thermal/thermal_zone*')
+ basenames = sorted(set(basenames))
+
+ for base in basenames:
+ try:
+ path = os.path.join(base, 'temp')
+ current = float(cat(path)) / 1000.0
+ path = os.path.join(base, 'type')
+ unit_name = cat(path, binary=False)
+ except (IOError, OSError, ValueError) as err:
+ warnings.warn("ignoring %r for file %r" % (err, path),
+ RuntimeWarning)
+ continue
+
+ trip_paths = glob.glob(base + '/trip_point*')
+ trip_points = set(['_'.join(
+ os.path.basename(p).split('_')[0:3]) for p in trip_paths])
+ critical = None
+ high = None
+ for trip_point in trip_points:
+ path = os.path.join(base, trip_point + "_type")
+ trip_type = cat(path, fallback='', binary=False)
+ if trip_type == 'critical':
+ critical = cat(os.path.join(base, trip_point + "_temp"),
+ fallback=None)
+ elif trip_type == 'high':
+ high = cat(os.path.join(base, trip_point + "_temp"),
+ fallback=None)
+
+ if high is not None:
+ try:
+ high = float(high) / 1000.0
+ except ValueError:
+ high = None
+ if critical is not None:
+ try:
+ critical = float(critical) / 1000.0
+ except ValueError:
+ critical = None
+
+ ret[unit_name].append(('', current, high, critical))
+
+ return dict(ret)
def sensors_fans():
@@ -1477,7 +1531,7 @@ def wrap_exceptions(fun):
class Process(object):
"""Linux process implementation."""
- __slots__ = ["pid", "_name", "_ppid", "_procfs_path"]
+ __slots__ = ["pid", "_name", "_ppid", "_procfs_path", "_cache"]
def __init__(self, pid):
self.pid = pid
@@ -1485,13 +1539,20 @@ class Process(object):
self._ppid = None
self._procfs_path = get_procfs_path()
+ def _assert_alive(self):
+ """Raise NSP if the process disappeared on us."""
+ # For those C function who do not raise NSP, possibly returning
+ # incorrect or incomplete result.
+ os.stat('%s/%s' % (self._procfs_path, self.pid))
+
+ @wrap_exceptions
@memoize_when_activated
def _parse_stat_file(self):
- """Parse /proc/{pid}/stat file. Return a list of fields where
- process name is in position 0.
+ """Parse /proc/{pid}/stat file and return a dict with various
+ process info.
Using "man proc" as a reference: where "man proc" refers to
- position N, always substract 2 (e.g starttime pos 22 in
- 'man proc' == pos 20 in the list returned here).
+ position N always substract 3 (e.g ppid position 4 in
+ 'man proc' == position 1 in here).
The return value is cached in case oneshot() ctx manager is
in use.
"""
@@ -1502,9 +1563,23 @@ class Process(object):
# the first occurrence of "(" and the last occurence of ")".
rpar = data.rfind(b')')
name = data[data.find(b'(') + 1:rpar]
- others = data[rpar + 2:].split()
- return [name] + others
+ fields = data[rpar + 2:].split()
+ ret = {}
+ ret['name'] = name
+ ret['status'] = fields[0]
+ ret['ppid'] = fields[1]
+ ret['ttynr'] = fields[4]
+ ret['utime'] = fields[11]
+ ret['stime'] = fields[12]
+ ret['children_utime'] = fields[13]
+ ret['children_stime'] = fields[14]
+ ret['create_time'] = fields[19]
+ ret['cpu_num'] = fields[36]
+
+ return ret
+
+ @wrap_exceptions
@memoize_when_activated
def _read_status_file(self):
"""Read /proc/{pid}/stat file and return its content.
@@ -1514,6 +1589,7 @@ class Process(object):
with open_binary("%s/%s/status" % (self._procfs_path, self.pid)) as f:
return f.read()
+ @wrap_exceptions
@memoize_when_activated
def _read_smaps_file(self):
with open_binary("%s/%s/smaps" % (self._procfs_path, self.pid),
@@ -1521,18 +1597,18 @@ class Process(object):
return f.read().strip()
def oneshot_enter(self):
- self._parse_stat_file.cache_activate()
- self._read_status_file.cache_activate()
- self._read_smaps_file.cache_activate()
+ self._parse_stat_file.cache_activate(self)
+ self._read_status_file.cache_activate(self)
+ self._read_smaps_file.cache_activate(self)
def oneshot_exit(self):
- self._parse_stat_file.cache_deactivate()
- self._read_status_file.cache_deactivate()
- self._read_smaps_file.cache_deactivate()
+ self._parse_stat_file.cache_deactivate(self)
+ self._read_status_file.cache_deactivate(self)
+ self._read_smaps_file.cache_deactivate(self)
@wrap_exceptions
def name(self):
- name = self._parse_stat_file()[0]
+ name = self._parse_stat_file()['name']
if PY3:
name = decode(name)
# XXX - gets changed later and probably needs refactoring
@@ -1574,7 +1650,7 @@ class Process(object):
sep = '\x00' if data.endswith('\x00') else ' '
if data.endswith(sep):
data = data[:-1]
- return [x for x in data.split(sep)]
+ return data.split(sep)
@wrap_exceptions
def environ(self):
@@ -1584,13 +1660,14 @@ class Process(object):
@wrap_exceptions
def terminal(self):
- tty_nr = int(self._parse_stat_file()[5])
+ tty_nr = int(self._parse_stat_file()['ttynr'])
tmap = _psposix.get_terminal_map()
try:
return tmap[tty_nr]
except KeyError:
return None
+ # May not be available on old kernels.
if os.path.exists('/proc/%s/io' % os.getpid()):
@wrap_exceptions
def io_counters(self):
@@ -1601,36 +1678,41 @@ class Process(object):
# https://github.com/giampaolo/psutil/issues/1004
line = line.strip()
if line:
- name, value = line.split(b': ')
- fields[name] = int(value)
+ try:
+ name, value = line.split(b': ')
+ except ValueError:
+ # https://github.com/giampaolo/psutil/issues/1004
+ continue
+ else:
+ fields[name] = int(value)
if not fields:
raise RuntimeError("%s file was empty" % fname)
- return pio(
- fields[b'syscr'], # read syscalls
- fields[b'syscw'], # write syscalls
- fields[b'read_bytes'], # read bytes
- fields[b'write_bytes'], # write bytes
- fields[b'rchar'], # read chars
- fields[b'wchar'], # write chars
- )
- else:
- def io_counters(self):
- raise NotImplementedError("couldn't find /proc/%s/io (kernel "
- "too old?)" % self.pid)
+ try:
+ return pio(
+ fields[b'syscr'], # read syscalls
+ fields[b'syscw'], # write syscalls
+ fields[b'read_bytes'], # read bytes
+ fields[b'write_bytes'], # write bytes
+ fields[b'rchar'], # read chars
+ fields[b'wchar'], # write chars
+ )
+ except KeyError as err:
+ raise ValueError("%r field was not found in %s; found fields "
+ "are %r" % (err[0], fname, fields))
@wrap_exceptions
def cpu_times(self):
values = self._parse_stat_file()
- utime = float(values[12]) / CLOCK_TICKS
- stime = float(values[13]) / CLOCK_TICKS
- children_utime = float(values[14]) / CLOCK_TICKS
- children_stime = float(values[15]) / CLOCK_TICKS
+ utime = float(values['utime']) / CLOCK_TICKS
+ stime = float(values['stime']) / CLOCK_TICKS
+ children_utime = float(values['children_utime']) / CLOCK_TICKS
+ children_stime = float(values['children_stime']) / CLOCK_TICKS
return _common.pcputimes(utime, stime, children_utime, children_stime)
@wrap_exceptions
def cpu_num(self):
"""What CPU the process is on."""
- return int(self._parse_stat_file()[37])
+ return int(self._parse_stat_file()['cpu_num'])
@wrap_exceptions
def wait(self, timeout=None):
@@ -1638,14 +1720,14 @@ class Process(object):
@wrap_exceptions
def create_time(self):
- values = self._parse_stat_file()
+ ctime = float(self._parse_stat_file()['create_time'])
# According to documentation, starttime is in field 21 and the
# unit is jiffies (clock ticks).
# We first divide it for clock ticks and then add uptime returning
# seconds since the epoch, in UTC.
# Also use cached value if available.
bt = BOOT_TIME or boot_time()
- return (float(values[20]) / CLOCK_TICKS) + bt
+ return (ctime / CLOCK_TICKS) + bt
@wrap_exceptions
def memory_info(self):
@@ -1707,6 +1789,9 @@ class Process(object):
"""Return process's mapped memory regions as a list of named
tuples. Fields are explained in 'man proc'; here is an updated
(Apr 2012) version: http://goo.gl/fmebo
+
+ /proc/{PID}/smaps does not exist on kernels < 2.6.14 or if
+ CONFIG_MMU kernel configuration option is not enabled.
"""
def get_blocks(lines, current_block):
data = {}
@@ -1767,13 +1852,6 @@ class Process(object):
))
return ls
- else: # pragma: no cover
- def memory_maps(self):
- raise NotImplementedError(
- "/proc/%s/smaps does not exist on kernels < 2.6.14 or "
- "if CONFIG_MMU kernel configuration option is not "
- "enabled." % self.pid)
-
@wrap_exceptions
def cwd(self):
try:
@@ -1836,8 +1914,7 @@ class Process(object):
ntuple = _common.pthread(int(thread_id), utime, stime)
retlist.append(ntuple)
if hit_enoent:
- # raise NSP if the process disappeared on us
- os.stat('%s/%s' % (self._procfs_path, self.pid))
+ self._assert_alive()
return retlist
@wrap_exceptions
@@ -1887,7 +1964,7 @@ class Process(object):
raise
# only starting from kernel 2.6.13
- if hasattr(cext, "proc_ioprio_get"):
+ if HAS_PROC_IO_PRIORITY:
@wrap_exceptions
def ionice_get(self):
@@ -1898,38 +1975,16 @@ class Process(object):
@wrap_exceptions
def ionice_set(self, ioclass, value):
- if value is not None:
- if not PY3 and not isinstance(value, (int, long)):
- msg = "value argument is not an integer (gor %r)" % value
- raise TypeError(msg)
- if not 0 <= value <= 7:
- raise ValueError(
- "value argument range expected is between 0 and 7")
-
- if ioclass in (IOPRIO_CLASS_NONE, None):
- if value:
- msg = "can't specify value with IOPRIO_CLASS_NONE " \
- "(got %r)" % value
- raise ValueError(msg)
- ioclass = IOPRIO_CLASS_NONE
+ if value is None:
value = 0
- elif ioclass == IOPRIO_CLASS_IDLE:
- if value:
- msg = "can't specify value with IOPRIO_CLASS_IDLE " \
- "(got %r)" % value
- raise ValueError(msg)
- value = 0
- elif ioclass in (IOPRIO_CLASS_RT, IOPRIO_CLASS_BE):
- if value is None:
- # TODO: add comment explaining why this is 4 (?)
- value = 4
- else:
- # otherwise we would get OSError(EVINAL)
- raise ValueError("invalid ioclass argument %r" % ioclass)
-
+ if value and ioclass in (IOPRIO_CLASS_IDLE, IOPRIO_CLASS_NONE):
+ raise ValueError("%r ioclass accepts no value" % ioclass)
+ if value < 0 or value > 7:
+ raise ValueError("value not in 0-7 range")
return cext.proc_ioprio_set(self.pid, ioclass, value)
if HAS_PRLIMIT:
+
@wrap_exceptions
def rlimit(self, resource, limits=None):
# If pid is 0 prlimit() applies to the calling process and
@@ -1959,7 +2014,7 @@ class Process(object):
@wrap_exceptions
def status(self):
- letter = self._parse_stat_file()[1]
+ letter = self._parse_stat_file()['status']
if PY3:
letter = letter.decode()
# XXX is '?' legit? (we're not supposed to return it anyway)
@@ -1999,9 +2054,8 @@ class Process(object):
flags = int(f.readline().split()[1], 8)
except IOError as err:
if err.errno == errno.ENOENT:
- # fd gone in the meantime; does not
- # necessarily mean the process disappeared
- # on us.
+ # fd gone in the meantime; process may
+ # still be alive
hit_enoent = True
else:
raise
@@ -2011,15 +2065,13 @@ class Process(object):
path, int(fd), int(pos), mode, flags)
retlist.append(ntuple)
if hit_enoent:
- # raise NSP if the process disappeared on us
- os.stat('%s/%s' % (self._procfs_path, self.pid))
+ self._assert_alive()
return retlist
@wrap_exceptions
def connections(self, kind='inet'):
ret = _connections.retrieve(kind, self.pid)
- # raise NSP if the process disappeared on us
- os.stat('%s/%s' % (self._procfs_path, self.pid))
+ self._assert_alive()
return ret
@wrap_exceptions
@@ -2028,7 +2080,7 @@ class Process(object):
@wrap_exceptions
def ppid(self):
- return int(self._parse_stat_file()[2])
+ return int(self._parse_stat_file()['ppid'])
@wrap_exceptions
def uids(self, _uids_re=re.compile(br'Uid:\t(\d+)\t(\d+)\t(\d+)')):
diff --git a/server/www/packages/packages-darwin/x64/psutil/_psosx.py b/server/www/packages/packages-darwin/x64/psutil/_psosx.py
index fbfedf3..7459a0f 100644
--- a/server/www/packages/packages-darwin/x64/psutil/_psosx.py
+++ b/server/www/packages/packages-darwin/x64/psutil/_psosx.py
@@ -23,9 +23,6 @@ from ._common import parse_environ_block
from ._common import sockfam_to_enum
from ._common import socktype_to_enum
from ._common import usage_percent
-from ._exceptions import AccessDenied
-from ._exceptions import NoSuchProcess
-from ._exceptions import ZombieProcess
__extra__all__ = []
@@ -87,6 +84,13 @@ pidtaskinfo_map = dict(
volctxsw=7,
)
+# These objects get set on "import psutil" from the __init__.py
+# file, see: https://github.com/giampaolo/psutil/issues/1402
+NoSuchProcess = None
+ZombieProcess = None
+AccessDenied = None
+TimeoutExpired = None
+
# =====================================================================
# --- named tuples
@@ -103,13 +107,6 @@ svmem = namedtuple(
pmem = namedtuple('pmem', ['rss', 'vms', 'pfaults', 'pageins'])
# psutil.Process.memory_full_info()
pfullmem = namedtuple('pfullmem', pmem._fields + ('uss', ))
-# psutil.Process.memory_maps(grouped=True)
-pmmap_grouped = namedtuple(
- 'pmmap_grouped',
- 'path rss private swapped dirtied ref_count shadow_depth')
-# psutil.Process.memory_maps(grouped=False)
-pmmap_ext = namedtuple(
- 'pmmap_ext', 'addr perms ' + ' '.join(pmmap_grouped._fields))
# =====================================================================
@@ -119,9 +116,16 @@ pmmap_ext = namedtuple(
def virtual_memory():
"""System virtual memory as a namedtuple."""
- total, active, inactive, wired, free = cext.virtual_mem()
+ total, active, inactive, wired, free, speculative = cext.virtual_mem()
+ # This is how Zabbix calculate avail and used mem:
+ # https://github.com/zabbix/zabbix/blob/trunk/src/libs/zbxsysinfo/
+ # osx/memory.c
+ # Also see: https://github.com/giampaolo/psutil/issues/1277
avail = inactive + free
- used = active + inactive + wired
+ used = active + wired
+ # This is NOT how Zabbix calculates free mem but it matches "free"
+ # cmdline utility.
+ free -= speculative
percent = usage_percent((total - avail), total, round_=1)
return svmem(total, avail, percent, used, free,
active, inactive, wired)
@@ -373,13 +377,14 @@ def catch_zombie(proc):
class Process(object):
"""Wrapper class around underlying C implementation."""
- __slots__ = ["pid", "_name", "_ppid"]
+ __slots__ = ["pid", "_name", "_ppid", "_cache"]
def __init__(self, pid):
self.pid = pid
self._name = None
self._ppid = None
+ @wrap_exceptions
@memoize_when_activated
def _get_kinfo_proc(self):
# Note: should work with all PIDs without permission issues.
@@ -387,6 +392,7 @@ class Process(object):
assert len(ret) == len(kinfo_proc_map)
return ret
+ @wrap_exceptions
@memoize_when_activated
def _get_pidtaskinfo(self):
# Note: should work for PIDs owned by user only.
@@ -396,12 +402,12 @@ class Process(object):
return ret
def oneshot_enter(self):
- self._get_kinfo_proc.cache_activate()
- self._get_pidtaskinfo.cache_activate()
+ self._get_kinfo_proc.cache_activate(self)
+ self._get_pidtaskinfo.cache_activate(self)
def oneshot_exit(self):
- self._get_kinfo_proc.cache_deactivate()
- self._get_pidtaskinfo.cache_deactivate()
+ self._get_kinfo_proc.cache_deactivate(self)
+ self._get_pidtaskinfo.cache_deactivate(self)
@wrap_exceptions
def name(self):
@@ -570,7 +576,3 @@ class Process(object):
ntuple = _common.pthread(thread_id, utime, stime)
retlist.append(ntuple)
return retlist
-
- @wrap_exceptions
- def memory_maps(self):
- return cext.proc_memory_maps(self.pid)
diff --git a/server/www/packages/packages-darwin/x64/psutil/_psposix.py b/server/www/packages/packages-darwin/x64/psutil/_psposix.py
index 9c3fac2..d362143 100644
--- a/server/www/packages/packages-darwin/x64/psutil/_psposix.py
+++ b/server/www/packages/packages-darwin/x64/psutil/_psposix.py
@@ -15,12 +15,16 @@ from ._common import sdiskusage
from ._common import usage_percent
from ._compat import PY3
from ._compat import unicode
-from ._exceptions import TimeoutExpired
__all__ = ['pid_exists', 'wait_pid', 'disk_usage', 'get_terminal_map']
+# This object gets set on "import psutil" from the __init__.py
+# file, see: https://github.com/giampaolo/psutil/issues/1402
+TimeoutExpired = None
+
+
def pid_exists(pid):
"""Check whether pid exists in the current process table."""
if pid == 0:
diff --git a/server/www/packages/packages-darwin/x64/psutil/_pssunos.py b/server/www/packages/packages-darwin/x64/psutil/_pssunos.py
index e2f33a3..6d7fda8 100644
--- a/server/www/packages/packages-darwin/x64/psutil/_pssunos.py
+++ b/server/www/packages/packages-darwin/x64/psutil/_pssunos.py
@@ -5,6 +5,7 @@
"""Sun OS Solaris platform implementation."""
import errno
+import functools
import os
import socket
import subprocess
@@ -17,6 +18,7 @@ from . import _psposix
from . import _psutil_posix as cext_posix
from . import _psutil_sunos as cext
from ._common import AF_INET6
+from ._common import get_procfs_path
from ._common import isfile_strict
from ._common import memoize_when_activated
from ._common import sockfam_to_enum
@@ -24,9 +26,6 @@ from ._common import socktype_to_enum
from ._common import usage_percent
from ._compat import b
from ._compat import PY3
-from ._exceptions import AccessDenied
-from ._exceptions import NoSuchProcess
-from ._exceptions import ZombieProcess
__extra__all__ = ["CONN_IDLE", "CONN_BOUND", "PROCFS_PATH"]
@@ -85,6 +84,13 @@ proc_info_map = dict(
gid=10,
egid=11)
+# These objects get set on "import psutil" from the __init__.py
+# file, see: https://github.com/giampaolo/psutil/issues/1402
+NoSuchProcess = None
+ZombieProcess = None
+AccessDenied = None
+TimeoutExpired = None
+
# =====================================================================
# --- named tuples
@@ -109,16 +115,6 @@ pmmap_ext = namedtuple(
'pmmap_ext', 'addr perms ' + ' '.join(pmmap_grouped._fields))
-# =====================================================================
-# --- utils
-# =====================================================================
-
-
-def get_procfs_path():
- """Return updated psutil.PROCFS_PATH constant."""
- return sys.modules['psutil'].PROCFS_PATH
-
-
# =====================================================================
# --- memory
# =====================================================================
@@ -341,7 +337,7 @@ def wrap_exceptions(fun):
"""Call callable into a try/except clause and translate ENOENT,
EACCES and EPERM in NoSuchProcess or AccessDenied exceptions.
"""
-
+ @functools.wraps(fun)
def wrapper(self, *args, **kwargs):
try:
return fun(self, *args, **kwargs)
@@ -368,7 +364,7 @@ def wrap_exceptions(fun):
class Process(object):
"""Wrapper class around underlying C implementation."""
- __slots__ = ["pid", "_name", "_ppid", "_procfs_path"]
+ __slots__ = ["pid", "_name", "_ppid", "_procfs_path", "_cache"]
def __init__(self, pid):
self.pid = pid
@@ -376,32 +372,38 @@ class Process(object):
self._ppid = None
self._procfs_path = get_procfs_path()
+ def _assert_alive(self):
+ """Raise NSP if the process disappeared on us."""
+ # For those C function who do not raise NSP, possibly returning
+ # incorrect or incomplete result.
+ os.stat('%s/%s' % (self._procfs_path, self.pid))
+
def oneshot_enter(self):
- self._proc_name_and_args.cache_activate()
- self._proc_basic_info.cache_activate()
- self._proc_cred.cache_activate()
+ self._proc_name_and_args.cache_activate(self)
+ self._proc_basic_info.cache_activate(self)
+ self._proc_cred.cache_activate(self)
def oneshot_exit(self):
- self._proc_name_and_args.cache_deactivate()
- self._proc_basic_info.cache_deactivate()
- self._proc_cred.cache_deactivate()
+ self._proc_name_and_args.cache_deactivate(self)
+ self._proc_basic_info.cache_deactivate(self)
+ self._proc_cred.cache_deactivate(self)
+ @wrap_exceptions
@memoize_when_activated
def _proc_name_and_args(self):
return cext.proc_name_and_args(self.pid, self._procfs_path)
+ @wrap_exceptions
@memoize_when_activated
def _proc_basic_info(self):
ret = cext.proc_basic_info(self.pid, self._procfs_path)
assert len(ret) == len(proc_info_map)
return ret
+ @wrap_exceptions
@memoize_when_activated
def _proc_cred(self):
- @wrap_exceptions
- def proc_cred(self):
- return cext.proc_cred(self.pid, self._procfs_path)
- return proc_cred(self)
+ return cext.proc_cred(self.pid, self._procfs_path)
@wrap_exceptions
def name(self):
@@ -518,8 +520,7 @@ class Process(object):
continue
raise
if hit_enoent:
- # raise NSP if the process disappeared on us
- os.stat('%s/%s' % (procfs_path, self.pid))
+ self._assert_alive()
@wrap_exceptions
def cwd(self):
@@ -581,8 +582,7 @@ class Process(object):
nt = _common.pthread(tid, utime, stime)
ret.append(nt)
if hit_enoent:
- # raise NSP if the process disappeared on us
- os.stat('%s/%s' % (procfs_path, self.pid))
+ self._assert_alive()
return ret
@wrap_exceptions
@@ -606,8 +606,7 @@ class Process(object):
if isfile_strict(file):
retlist.append(_common.popenfile(file, int(fd)))
if hit_enoent:
- # raise NSP if the process disappeared on us
- os.stat('%s/%s' % (procfs_path, self.pid))
+ self._assert_alive()
return retlist
def _get_unix_sockets(self, pid):
@@ -707,8 +706,7 @@ class Process(object):
raise
retlist.append((addr, perm, name, rss, anon, locked))
if hit_enoent:
- # raise NSP if the process disappeared on us
- os.stat('%s/%s' % (procfs_path, self.pid))
+ self._assert_alive()
return retlist
@wrap_exceptions
diff --git a/server/www/packages/packages-darwin/x64/psutil/_psutil_osx.cpython-37m-darwin.so b/server/www/packages/packages-darwin/x64/psutil/_psutil_osx.cpython-37m-darwin.so
index 9d038ca..7eec7af 100755
Binary files a/server/www/packages/packages-darwin/x64/psutil/_psutil_osx.cpython-37m-darwin.so and b/server/www/packages/packages-darwin/x64/psutil/_psutil_osx.cpython-37m-darwin.so differ
diff --git a/server/www/packages/packages-darwin/x64/psutil/_psutil_posix.cpython-37m-darwin.so b/server/www/packages/packages-darwin/x64/psutil/_psutil_posix.cpython-37m-darwin.so
index ccc4304..3f69a2f 100755
Binary files a/server/www/packages/packages-darwin/x64/psutil/_psutil_posix.cpython-37m-darwin.so and b/server/www/packages/packages-darwin/x64/psutil/_psutil_posix.cpython-37m-darwin.so differ
diff --git a/server/www/packages/packages-darwin/x64/psutil/_pswindows.py b/server/www/packages/packages-darwin/x64/psutil/_pswindows.py
index 18651d6..3f13198 100644
--- a/server/www/packages/packages-darwin/x64/psutil/_pswindows.py
+++ b/server/www/packages/packages-darwin/x64/psutil/_pswindows.py
@@ -27,8 +27,7 @@ except ImportError as err:
# but if we get here it means this this was a wheel (or exe).
msg = "this Windows version is too old (< Windows Vista); "
msg += "psutil 3.4.2 is the latest version which supports Windows "
- msg += "2000, XP and 2003 server; it may be possible that psutil "
- msg += "will work if compiled from sources though"
+ msg += "2000, XP and 2003 server"
raise RuntimeError(msg)
else:
raise
@@ -37,6 +36,7 @@ from ._common import conn_tmap
from ._common import ENCODING
from ._common import ENCODING_ERRS
from ._common import isfile_strict
+from ._common import memoize
from ._common import memoize_when_activated
from ._common import parse_environ_block
from ._common import sockfam_to_enum
@@ -47,9 +47,6 @@ from ._compat import lru_cache
from ._compat import PY3
from ._compat import unicode
from ._compat import xrange
-from ._exceptions import AccessDenied
-from ._exceptions import NoSuchProcess
-from ._exceptions import TimeoutExpired
from ._psutil_windows import ABOVE_NORMAL_PRIORITY_CLASS
from ._psutil_windows import BELOW_NORMAL_PRIORITY_CLASS
from ._psutil_windows import HIGH_PRIORITY_CLASS
@@ -66,11 +63,14 @@ else:
# http://msdn.microsoft.com/en-us/library/ms686219(v=vs.85).aspx
__extra__all__ = [
"win_service_iter", "win_service_get",
+ # Process priority
"ABOVE_NORMAL_PRIORITY_CLASS", "BELOW_NORMAL_PRIORITY_CLASS",
- "HIGH_PRIORITY_CLASS", "IDLE_PRIORITY_CLASS",
- "NORMAL_PRIORITY_CLASS", "REALTIME_PRIORITY_CLASS",
- "CONN_DELETE_TCB",
- "AF_LINK",
+ "HIGH_PRIORITY_CLASS", "IDLE_PRIORITY_CLASS", "NORMAL_PRIORITY_CLASS",
+ "REALTIME_PRIORITY_CLASS",
+ # IO priority
+ "IOPRIO_VERYLOW", "IOPRIO_LOW", "IOPRIO_NORMAL", "IOPRIO_HIGH",
+ # others
+ "CONN_DELETE_TCB", "AF_LINK",
]
@@ -79,10 +79,8 @@ __extra__all__ = [
# =====================================================================
CONN_DELETE_TCB = "DELETE_TCB"
-ACCESS_DENIED_ERRSET = frozenset([errno.EPERM, errno.EACCES,
- cext.ERROR_ACCESS_DENIED])
-NO_SUCH_SERVICE_ERRSET = frozenset([cext.ERROR_INVALID_NAME,
- cext.ERROR_SERVICE_DOES_NOT_EXIST])
+HAS_PROC_IO_PRIORITY = hasattr(cext, "proc_io_priority_get")
+HAS_GETLOADAVG = hasattr(cext, "getloadavg")
if enum is None:
@@ -118,6 +116,19 @@ if enum is not None:
globals().update(Priority.__members__)
+if enum is None:
+ IOPRIO_VERYLOW = 0
+ IOPRIO_LOW = 1
+ IOPRIO_NORMAL = 2
+ IOPRIO_HIGH = 3
+else:
+ class IOPriority(enum.IntEnum):
+ IOPRIO_VERYLOW = 0
+ IOPRIO_LOW = 1
+ IOPRIO_NORMAL = 2
+ IOPRIO_HIGH = 3
+ globals().update(IOPriority.__members__)
+
pinfo_map = dict(
num_handles=0,
ctx_switches=1,
@@ -143,6 +154,35 @@ pinfo_map = dict(
mem_private=21,
)
+# These objects get set on "import psutil" from the __init__.py
+# file, see: https://github.com/giampaolo/psutil/issues/1402
+NoSuchProcess = None
+ZombieProcess = None
+AccessDenied = None
+TimeoutExpired = None
+
+# More values at: https://stackoverflow.com/a/20804735/376587
+WIN_10 = (10, 0)
+WIN_8 = (6, 2)
+WIN_7 = (6, 1)
+WIN_SERVER_2008 = (6, 0)
+WIN_VISTA = (6, 0)
+WIN_SERVER_2003 = (5, 2)
+WIN_XP = (5, 1)
+
+
+@lru_cache()
+def get_winver():
+ """Usage:
+ >>> if get_winver() <= WIN_VISTA:
+ ... ...
+ """
+ wv = sys.getwindowsversion()
+ return (wv.major, wv.minor)
+
+
+IS_WIN_XP = get_winver() < WIN_VISTA
+
# =====================================================================
# --- named tuples
@@ -203,6 +243,11 @@ def py2_strencode(s):
return s.encode(ENCODING, ENCODING_ERRS)
+@memoize
+def getpagesize():
+ return cext.getpagesize()
+
+
# =====================================================================
# --- memory
# =====================================================================
@@ -309,6 +354,23 @@ def cpu_freq():
return [_common.scpufreq(float(curr), min_, float(max_))]
+if HAS_GETLOADAVG:
+ _loadavg_inititialized = False
+
+ def getloadavg():
+ """Return the number of processes in the system run queue averaged
+ over the last 1, 5, and 15 minutes respectively as a tuple"""
+ global _loadavg_inititialized
+
+ if not _loadavg_inititialized:
+ cext.init_loadavg_counter()
+ _loadavg_inititialized = True
+
+ # Drop to 2 decimal points which is what Linux does
+ raw_loads = cext.getloadavg()
+ return tuple([round(load, 2) for load in raw_loads])
+
+
# =====================================================================
# --- network
# =====================================================================
@@ -501,14 +563,14 @@ class WindowsService(object):
"""
try:
yield
- except WindowsError as err:
- if err.errno in ACCESS_DENIED_ERRSET:
+ except OSError as err:
+ if is_permission_err(err):
raise AccessDenied(
pid=None, name=self._name,
msg="service %r is not querable (not enough privileges)" %
self._name)
- elif err.errno in NO_SUCH_SERVICE_ERRSET or \
- err.winerror in NO_SUCH_SERVICE_ERRSET:
+ elif err.winerror in (cext.ERROR_INVALID_NAME,
+ cext.ERROR_SERVICE_DOES_NOT_EXIST):
raise NoSuchProcess(
pid=None, name=self._name,
msg="service %r does not exist)" % self._name)
@@ -625,27 +687,42 @@ pid_exists = cext.pid_exists
ppid_map = cext.ppid_map # used internally by Process.children()
+def is_permission_err(exc):
+ """Return True if this is a permission error."""
+ assert isinstance(exc, OSError), exc
+ # On Python 2 OSError doesn't always have 'winerror'. Sometimes
+ # it does, in which case the original exception was WindowsError
+ # (which is a subclass of OSError).
+ return exc.errno in (errno.EPERM, errno.EACCES) or \
+ getattr(exc, "winerror", -1) in (cext.ERROR_ACCESS_DENIED,
+ cext.ERROR_PRIVILEGE_NOT_HELD)
+
+
+def convert_oserror(exc, pid=None, name=None):
+ """Convert OSError into NoSuchProcess or AccessDenied."""
+ assert isinstance(exc, OSError), exc
+ if is_permission_err(exc):
+ return AccessDenied(pid=pid, name=name)
+ if exc.errno == errno.ESRCH:
+ return NoSuchProcess(pid=pid, name=name)
+ raise exc
+
+
def wrap_exceptions(fun):
- """Decorator which translates bare OSError and WindowsError
- exceptions into NoSuchProcess and AccessDenied.
- """
+ """Decorator which converts OSError into NoSuchProcess or AccessDenied."""
@functools.wraps(fun)
def wrapper(self, *args, **kwargs):
try:
return fun(self, *args, **kwargs)
except OSError as err:
- if err.errno in ACCESS_DENIED_ERRSET:
- raise AccessDenied(self.pid, self._name)
- if err.errno == errno.ESRCH:
- raise NoSuchProcess(self.pid, self._name)
- raise
+ raise convert_oserror(err, pid=self.pid, name=self._name)
return wrapper
class Process(object):
"""Wrapper class around underlying C implementation."""
- __slots__ = ["pid", "_name", "_ppid"]
+ __slots__ = ["pid", "_name", "_ppid", "_cache"]
def __init__(self, pid):
self.pid = pid
@@ -655,11 +732,12 @@ class Process(object):
# --- oneshot() stuff
def oneshot_enter(self):
- self.oneshot_info.cache_activate()
+ self.oneshot_info.cache_activate(self)
def oneshot_exit(self):
- self.oneshot_info.cache_deactivate()
+ self.oneshot_info.cache_deactivate(self)
+ @wrap_exceptions
@memoize_when_activated
def oneshot_info(self):
"""Return multiple information about this process as a
@@ -690,19 +768,33 @@ class Process(object):
@wrap_exceptions
def exe(self):
- # Note: os.path.exists(path) may return False even if the file
- # is there, see:
- # http://stackoverflow.com/questions/3112546/os-path-exists-lies
-
- # see https://github.com/giampaolo/psutil/issues/414
- # see https://github.com/giampaolo/psutil/issues/528
- if self.pid in (0, 4):
- raise AccessDenied(self.pid, self._name)
- return py2_strencode(convert_dos_path(cext.proc_exe(self.pid)))
+ # Dual implementation, see:
+ # https://github.com/giampaolo/psutil/pull/1413
+ if not IS_WIN_XP:
+ exe = cext.proc_exe(self.pid)
+ else:
+ if self.pid in (0, 4):
+ # https://github.com/giampaolo/psutil/issues/414
+ # https://github.com/giampaolo/psutil/issues/528
+ raise AccessDenied(self.pid, self._name)
+ exe = cext.proc_exe(self.pid)
+ exe = convert_dos_path(exe)
+ return py2_strencode(exe)
@wrap_exceptions
def cmdline(self):
- ret = cext.proc_cmdline(self.pid)
+ if cext.WINVER >= cext.WINDOWS_8_1:
+ # PEB method detects cmdline changes but requires more
+ # privileges: https://github.com/giampaolo/psutil/pull/1398
+ try:
+ ret = cext.proc_cmdline(self.pid, use_peb=True)
+ except OSError as err:
+ if is_permission_err(err):
+ ret = cext.proc_cmdline(self.pid, use_peb=False)
+ else:
+ raise
+ else:
+ ret = cext.proc_cmdline(self.pid, use_peb=True)
if PY3:
return ret
else:
@@ -725,7 +817,7 @@ class Process(object):
try:
return cext.proc_memory_info(self.pid)
except OSError as err:
- if err.errno in ACCESS_DENIED_ERRSET:
+ if is_permission_err(err):
# TODO: the C ext can probably be refactored in order
# to get this from cext.proc_info()
info = self.oneshot_info()
@@ -757,6 +849,7 @@ class Process(object):
def memory_full_info(self):
basic_mem = self.memory_info()
uss = cext.proc_memory_uss(self.pid)
+ uss *= getpagesize()
return pfullmem(*basic_mem + (uss, ))
def memory_maps(self):
@@ -765,11 +858,7 @@ class Process(object):
except OSError as err:
# XXX - can't use wrap_exceptions decorator as we're
# returning a generator; probably needs refactoring.
- if err.errno in ACCESS_DENIED_ERRSET:
- raise AccessDenied(self.pid, self._name)
- if err.errno == errno.ESRCH:
- raise NoSuchProcess(self.pid, self._name)
- raise
+ raise convert_oserror(err, self.pid, self._name)
else:
for addr, perm, path, rss in raw:
path = convert_dos_path(path)
@@ -845,7 +934,7 @@ class Process(object):
try:
return cext.proc_create_time(self.pid)
except OSError as err:
- if err.errno in ACCESS_DENIED_ERRSET:
+ if is_permission_err(err):
return self.oneshot_info()[pinfo_map['create_time']]
raise
@@ -867,22 +956,21 @@ class Process(object):
try:
user, system = cext.proc_cpu_times(self.pid)
except OSError as err:
- if err.errno in ACCESS_DENIED_ERRSET:
- info = self.oneshot_info()
- user = info[pinfo_map['user_time']]
- system = info[pinfo_map['kernel_time']]
- else:
+ if not is_permission_err(err):
raise
+ info = self.oneshot_info()
+ user = info[pinfo_map['user_time']]
+ system = info[pinfo_map['kernel_time']]
# Children user/system times are not retrievable (set to 0).
return _common.pcputimes(user, system, 0.0, 0.0)
@wrap_exceptions
def suspend(self):
- return cext.proc_suspend(self.pid)
+ cext.proc_suspend_or_resume(self.pid, True)
@wrap_exceptions
def resume(self):
- return cext.proc_resume(self.pid)
+ cext.proc_suspend_or_resume(self.pid, False)
@wrap_exceptions
def cwd(self):
@@ -928,38 +1016,39 @@ class Process(object):
return cext.proc_priority_set(self.pid, value)
# available on Windows >= Vista
- if hasattr(cext, "proc_io_priority_get"):
+ if HAS_PROC_IO_PRIORITY:
@wrap_exceptions
def ionice_get(self):
- return cext.proc_io_priority_get(self.pid)
+ ret = cext.proc_io_priority_get(self.pid)
+ if enum is not None:
+ ret = IOPriority(ret)
+ return ret
@wrap_exceptions
- def ionice_set(self, value, _):
- if _:
- raise TypeError("set_proc_ionice() on Windows takes only "
- "1 argument (2 given)")
- if value not in (2, 1, 0):
- raise ValueError("value must be 2 (normal), 1 (low) or 0 "
- "(very low); got %r" % value)
- return cext.proc_io_priority_set(self.pid, value)
+ def ionice_set(self, ioclass, value):
+ if value:
+ raise TypeError("value argument not accepted on Windows")
+ if ioclass not in (IOPRIO_VERYLOW, IOPRIO_LOW, IOPRIO_NORMAL,
+ IOPRIO_HIGH):
+ raise ValueError("%s is not a valid priority" % ioclass)
+ cext.proc_io_priority_set(self.pid, ioclass)
@wrap_exceptions
def io_counters(self):
try:
ret = cext.proc_io_counters(self.pid)
except OSError as err:
- if err.errno in ACCESS_DENIED_ERRSET:
- info = self.oneshot_info()
- ret = (
- info[pinfo_map['io_rcount']],
- info[pinfo_map['io_wcount']],
- info[pinfo_map['io_rbytes']],
- info[pinfo_map['io_wbytes']],
- info[pinfo_map['io_count_others']],
- info[pinfo_map['io_bytes_others']],
- )
- else:
+ if not is_permission_err(err):
raise
+ info = self.oneshot_info()
+ ret = (
+ info[pinfo_map['io_rcount']],
+ info[pinfo_map['io_wcount']],
+ info[pinfo_map['io_rbytes']],
+ info[pinfo_map['io_wbytes']],
+ info[pinfo_map['io_count_others']],
+ info[pinfo_map['io_bytes_others']],
+ )
return pio(*ret)
@wrap_exceptions
@@ -1007,7 +1096,7 @@ class Process(object):
try:
return cext.proc_num_handles(self.pid)
except OSError as err:
- if err.errno in ACCESS_DENIED_ERRSET:
+ if is_permission_err(err):
return self.oneshot_info()[pinfo_map['num_handles']]
raise
diff --git a/server/www/packages/packages-darwin/x64/psutil/tests/__init__.py b/server/www/packages/packages-darwin/x64/psutil/tests/__init__.py
deleted file mode 100644
index a483eca..0000000
--- a/server/www/packages/packages-darwin/x64/psutil/tests/__init__.py
+++ /dev/null
@@ -1,1241 +0,0 @@
-# -*- 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.
-
-"""
-Test utilities.
-"""
-
-from __future__ import print_function
-
-import atexit
-import contextlib
-import ctypes
-import errno
-import functools
-import os
-import random
-import re
-import select
-import shutil
-import socket
-import stat
-import subprocess
-import sys
-import tempfile
-import textwrap
-import threading
-import time
-import traceback
-import warnings
-from socket import AF_INET
-from socket import AF_INET6
-from socket import SOCK_DGRAM
-from socket import SOCK_STREAM
-
-import psutil
-from psutil import MACOS
-from psutil import POSIX
-from psutil import SUNOS
-from psutil import WINDOWS
-from psutil._common import supports_ipv6
-from psutil._compat import PY3
-from psutil._compat import u
-from psutil._compat import unicode
-from psutil._compat import which
-
-if sys.version_info < (2, 7):
- import unittest2 as unittest # requires "pip install unittest2"
-else:
- import unittest
-
-try:
- from unittest import mock # py3
-except ImportError:
- with warnings.catch_warnings():
- warnings.simplefilter("ignore")
- import mock # NOQA - requires "pip install mock"
-
-if sys.version_info >= (3, 4):
- import enum
-else:
- enum = None
-
-
-__all__ = [
- # constants
- 'APPVEYOR', 'DEVNULL', 'GLOBAL_TIMEOUT', 'MEMORY_TOLERANCE', 'NO_RETRIES',
- 'PYPY', 'PYTHON_EXE', 'ROOT_DIR', 'SCRIPTS_DIR', 'TESTFILE_PREFIX',
- 'TESTFN', 'TESTFN_UNICODE', 'TOX', 'TRAVIS', 'VALID_PROC_STATUSES',
- 'VERBOSITY',
- "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_TEMPERATURES", "HAS_MEMORY_FULL_INFO",
- # subprocesses
- 'pyrun', 'reap_children', 'get_test_subprocess', 'create_zombie_proc',
- 'create_proc_children_pair',
- # threads
- 'ThreadTask'
- # test utils
- 'unittest', 'skip_on_access_denied', 'skip_on_not_implemented',
- 'retry_before_failing', 'run_test_module_by_name', 'get_suite',
- 'run_suite',
- # install utils
- 'install_pip', 'install_test_deps',
- # fs utils
- 'chdir', 'safe_rmpath', 'create_exe', 'decode_path', 'encode_path',
- 'unique_filename',
- # os
- 'get_winver', 'get_kernel_version',
- # sync primitives
- 'call_until', 'wait_for_pid', 'wait_for_file',
- # network
- 'check_connection_ntuple', 'check_net_address',
- 'get_free_port', 'unix_socket_path', 'bind_socket', 'bind_unix_socket',
- 'tcp_socketpair', 'unix_socketpair', 'create_sockets',
- # compat
- 'reload_module', 'import_module_by_path',
- # others
- 'warn', 'copyload_shared_lib', 'is_namedtuple',
-]
-
-
-# ===================================================================
-# --- constants
-# ===================================================================
-
-# --- platforms
-
-TOX = os.getenv('TOX') or '' in ('1', 'true')
-PYPY = '__pypy__' in sys.builtin_module_names
-WIN_VISTA = (6, 0, 0) if WINDOWS else None
-# whether we're running this test suite on Travis (https://travis-ci.org/)
-TRAVIS = bool(os.environ.get('TRAVIS'))
-# whether we're running this test suite on Appveyor for Windows
-# (http://www.appveyor.com/)
-APPVEYOR = bool(os.environ.get('APPVEYOR'))
-
-# --- configurable defaults
-
-# how many times retry_before_failing() decorator will retry
-NO_RETRIES = 10
-# bytes tolerance for system-wide memory related tests
-MEMORY_TOLERANCE = 500 * 1024 # 500KB
-# the timeout used in functions which have to wait
-GLOBAL_TIMEOUT = 3 if TRAVIS or APPVEYOR else 0.5
-# test output verbosity
-VERBOSITY = 1 if os.getenv('SILENT') or TOX else 2
-# be more tolerant if we're on travis / appveyor in order to avoid
-# false positives
-if TRAVIS or APPVEYOR:
- NO_RETRIES *= 3
- GLOBAL_TIMEOUT *= 3
-
-# --- files
-
-TESTFILE_PREFIX = '$testfn'
-if os.name == 'java':
- # Jython disallows @ in module names
- TESTFILE_PREFIX = '$psutil-test-'
-else:
- TESTFILE_PREFIX = '@psutil-test-'
-TESTFN = os.path.join(os.path.realpath(os.getcwd()), TESTFILE_PREFIX)
-# Disambiguate TESTFN for parallel testing, while letting it remain a valid
-# module name.
-TESTFN = TESTFN + str(os.getpid())
-
-_TESTFN = TESTFN + '-internal'
-TESTFN_UNICODE = TESTFN + u("-ƒőő")
-ASCII_FS = sys.getfilesystemencoding().lower() in ('ascii', 'us-ascii')
-
-# --- paths
-
-ROOT_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..'))
-SCRIPTS_DIR = os.path.join(ROOT_DIR, 'scripts')
-HERE = os.path.abspath(os.path.dirname(__file__))
-
-# --- support
-
-HAS_CPU_AFFINITY = hasattr(psutil.Process, "cpu_affinity")
-HAS_CPU_FREQ = hasattr(psutil, "cpu_freq")
-HAS_CONNECTIONS_UNIX = POSIX and not SUNOS
-HAS_ENVIRON = hasattr(psutil.Process, "environ")
-HAS_PROC_IO_COUNTERS = hasattr(psutil.Process, "io_counters")
-HAS_IONICE = hasattr(psutil.Process, "ionice")
-HAS_MEMORY_FULL_INFO = 'uss' in psutil.Process().memory_full_info()._fields
-HAS_MEMORY_MAPS = hasattr(psutil.Process, "memory_maps")
-HAS_PROC_CPU_NUM = hasattr(psutil.Process, "cpu_num")
-HAS_RLIMIT = hasattr(psutil.Process, "rlimit")
-HAS_THREADS = hasattr(psutil.Process, "threads")
-HAS_SENSORS_BATTERY = hasattr(psutil, "sensors_battery")
-HAS_BATTERY = HAS_SENSORS_BATTERY and bool(psutil.sensors_battery())
-HAS_SENSORS_FANS = hasattr(psutil, "sensors_fans")
-HAS_SENSORS_TEMPERATURES = hasattr(psutil, "sensors_temperatures")
-
-# --- misc
-
-
-def _get_py_exe():
- def attempt(exe):
- try:
- subprocess.check_call(
- [exe, "-V"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
- except Exception:
- return None
- else:
- return exe
-
- if MACOS:
- exe = \
- attempt(sys.executable) or \
- attempt(os.path.realpath(sys.executable)) or \
- attempt(which("python%s.%s" % sys.version_info[:2])) or \
- attempt(psutil.Process().exe())
- if not exe:
- raise ValueError("can't find python exe real abspath")
- return exe
- else:
- exe = os.path.realpath(sys.executable)
- assert os.path.exists(exe), exe
- return exe
-
-
-PYTHON_EXE = _get_py_exe()
-DEVNULL = open(os.devnull, 'r+')
-VALID_PROC_STATUSES = [getattr(psutil, x) for x in dir(psutil)
- if x.startswith('STATUS_')]
-AF_UNIX = getattr(socket, "AF_UNIX", object())
-SOCK_SEQPACKET = getattr(socket, "SOCK_SEQPACKET", object())
-
-_subprocesses_started = set()
-_pids_started = set()
-_testfiles_created = set()
-
-
-def logstderr(s):
- print(s, file=sys.stderr)
-
-
-@atexit.register
-def cleanup_test_files():
- logstderr("executing cleanup_test_files() atexit function")
- DEVNULL.close()
- for name in os.listdir(u('.')):
- if isinstance(name, unicode):
- prefix = u(TESTFILE_PREFIX)
- else:
- prefix = TESTFILE_PREFIX
- if name.startswith(prefix):
- logstderr("removing temporary test file %r" % name)
- try:
- safe_rmpath(name)
- except Exception:
- traceback.print_exc()
- for path in _testfiles_created:
- logstderr("removing temporary test file %r" % path)
- try:
- safe_rmpath(path)
- except Exception:
- traceback.print_exc()
-
-
-# this is executed first
-@atexit.register
-def cleanup_test_procs():
- logstderr("executing cleanup_test_procs() atexit function")
- reap_children(recursive=True)
-
-
-# ===================================================================
-# --- threads
-# ===================================================================
-
-
-class ThreadTask(threading.Thread):
- """A thread task which does nothing expect staying alive."""
-
- def __init__(self):
- threading.Thread.__init__(self)
- self._running = False
- self._interval = 0.001
- self._flag = threading.Event()
-
- def __repr__(self):
- name = self.__class__.__name__
- return '<%s running=%s at %#x>' % (name, self._running, id(self))
-
- def __enter__(self):
- self.start()
- return self
-
- def __exit__(self, *args, **kwargs):
- self.stop()
-
- def start(self):
- """Start thread and keep it running until an explicit
- stop() request. Polls for shutdown every 'timeout' seconds.
- """
- if self._running:
- raise ValueError("already started")
- threading.Thread.start(self)
- self._flag.wait()
-
- def run(self):
- self._running = True
- self._flag.set()
- while self._running:
- time.sleep(self._interval)
-
- def stop(self):
- """Stop thread execution and and waits until it is stopped."""
- if not self._running:
- raise ValueError("already stopped")
- self._running = False
- self.join()
-
-
-# ===================================================================
-# --- subprocesses
-# ===================================================================
-
-
-def _reap_children_on_err(fun):
- @functools.wraps(fun)
- def wrapper(*args, **kwargs):
- try:
- return fun(*args, **kwargs)
- except Exception:
- reap_children()
- raise
- return wrapper
-
-
-@_reap_children_on_err
-def get_test_subprocess(cmd=None, **kwds):
- """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().
- """
- kwds.setdefault("stdin", DEVNULL)
- kwds.setdefault("stdout", DEVNULL)
- kwds.setdefault("cwd", os.getcwd())
- kwds.setdefault("env", os.environ)
- if WINDOWS:
- # Prevents the subprocess to open error dialogs.
- kwds.setdefault("creationflags", 0x8000000) # CREATE_NO_WINDOW
- if cmd is None:
- safe_rmpath(_TESTFN)
- pyline = "from time import sleep;" \
- "open(r'%s', 'w').close();" \
- "sleep(60);" % _TESTFN
- cmd = [PYTHON_EXE, "-c", pyline]
- sproc = subprocess.Popen(cmd, **kwds)
- _subprocesses_started.add(sproc)
- wait_for_file(_TESTFN, delete=True, empty=True)
- else:
- sproc = subprocess.Popen(cmd, **kwds)
- _subprocesses_started.add(sproc)
- wait_for_pid(sproc.pid)
- return sproc
-
-
-@_reap_children_on_err
-def create_proc_children_pair():
- """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().
- """
- _TESTFN2 = os.path.basename(_TESTFN) + '2' # need to be relative
- s = textwrap.dedent("""\
- 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)
- """ % (_TESTFN2, PYTHON_EXE))
- # On Windows if we create a subprocess with CREATE_NO_WINDOW flag
- # set (which is the default) a "conhost.exe" extra process will be
- # spawned as a child. We don't want that.
- if WINDOWS:
- subp = pyrun(s, creationflags=0)
- else:
- subp = pyrun(s)
- child1 = psutil.Process(subp.pid)
- data = wait_for_file(_TESTFN2, delete=False, empty=False)
- safe_rmpath(_TESTFN2)
- child2_pid = int(data)
- _pids_started.add(child2_pid)
- child2 = psutil.Process(child2_pid)
- return (child1, child2)
-
-
-def create_zombie_proc():
- """Create a zombie process and return its PID."""
- assert psutil.POSIX
- unix_file = tempfile.mktemp(prefix=TESTFILE_PREFIX) if MACOS else TESTFN
- src = textwrap.dedent("""\
- 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)
- """ % unix_file)
- with contextlib.closing(socket.socket(socket.AF_UNIX)) as sock:
- sock.settimeout(GLOBAL_TIMEOUT)
- sock.bind(unix_file)
- sock.listen(1)
- pyrun(src)
- conn, _ = sock.accept()
- try:
- select.select([conn.fileno()], [], [], GLOBAL_TIMEOUT)
- zpid = int(conn.recv(1024))
- _pids_started.add(zpid)
- zproc = psutil.Process(zpid)
- call_until(lambda: zproc.status(), "ret == psutil.STATUS_ZOMBIE")
- return zpid
- finally:
- conn.close()
-
-
-@_reap_children_on_err
-def pyrun(src, **kwds):
- """Run python 'src' code string in a separate interpreter.
- Returns a subprocess.Popen instance.
- """
- kwds.setdefault("stdout", None)
- kwds.setdefault("stderr", None)
- with tempfile.NamedTemporaryFile(
- prefix=TESTFILE_PREFIX, mode="wt", delete=False) as f:
- _testfiles_created.add(f.name)
- f.write(src)
- f.flush()
- subp = get_test_subprocess([PYTHON_EXE, f.name], **kwds)
- wait_for_pid(subp.pid)
- return subp
-
-
-@_reap_children_on_err
-def sh(cmd, **kwds):
- """run cmd in a subprocess and return its output.
- raises RuntimeError on error.
- """
- shell = True if isinstance(cmd, (str, unicode)) else False
- # Prevents subprocess to open error dialogs in case of error.
- flags = 0x8000000 if WINDOWS and shell else 0
- kwds.setdefault("shell", shell)
- kwds.setdefault("stdout", subprocess.PIPE)
- kwds.setdefault("stderr", subprocess.PIPE)
- kwds.setdefault("universal_newlines", True)
- kwds.setdefault("creationflags", flags)
- p = subprocess.Popen(cmd, **kwds)
- _subprocesses_started.add(p)
- stdout, stderr = p.communicate()
- if p.returncode != 0:
- raise RuntimeError(stderr)
- if stderr:
- warn(stderr)
- if stdout.endswith('\n'):
- stdout = stdout[:-1]
- return stdout
-
-
-def reap_children(recursive=False):
- """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.
- """
- # This is here to make sure wait_procs() behaves properly and
- # investigate:
- # https://ci.appveyor.com/project/giampaolo/psutil/build/job/
- # jiq2cgd6stsbtn60
- def assert_gone(pid):
- assert not psutil.pid_exists(pid), pid
- assert pid not in psutil.pids(), pid
- try:
- p = psutil.Process(pid)
- assert not p.is_running(), pid
- except psutil.NoSuchProcess:
- pass
- else:
- assert 0, "pid %s is not gone" % pid
-
- # Get the children here, before terminating the children sub
- # processes as we don't want to lose the intermediate reference
- # in case of grandchildren.
- if recursive:
- children = set(psutil.Process().children(recursive=True))
- else:
- children = set()
-
- # Terminate subprocess.Popen instances "cleanly" by closing their
- # fds and wiat()ing for them in order to avoid zombies.
- while _subprocesses_started:
- subp = _subprocesses_started.pop()
- _pids_started.add(subp.pid)
- try:
- subp.terminate()
- except OSError as err:
- if WINDOWS and err.errno == 6: # "invalid handle"
- pass
- elif err.errno != errno.ESRCH:
- raise
- if subp.stdout:
- subp.stdout.close()
- if subp.stderr:
- subp.stderr.close()
- try:
- # Flushing a BufferedWriter may raise an error.
- if subp.stdin:
- subp.stdin.close()
- finally:
- # Wait for the process to terminate, to avoid zombies.
- try:
- subp.wait()
- except OSError as err:
- if err.errno != errno.ECHILD:
- raise
-
- # Terminate started pids.
- while _pids_started:
- pid = _pids_started.pop()
- try:
- p = psutil.Process(pid)
- except psutil.NoSuchProcess:
- assert_gone(pid)
- else:
- children.add(p)
-
- # Terminate children.
- if children:
- for p in children:
- try:
- p.terminate()
- except psutil.NoSuchProcess:
- pass
- gone, alive = psutil.wait_procs(children, timeout=GLOBAL_TIMEOUT)
- for p in alive:
- warn("couldn't terminate process %r; attempting kill()" % p)
- try:
- p.kill()
- except psutil.NoSuchProcess:
- pass
- gone, alive = psutil.wait_procs(alive, timeout=GLOBAL_TIMEOUT)
- if alive:
- for p in alive:
- warn("process %r survived kill()" % p)
-
- for p in children:
- assert_gone(p.pid)
-
-
-# ===================================================================
-# --- OS
-# ===================================================================
-
-
-def get_kernel_version():
- """Return a tuple such as (2, 6, 36)."""
- if not POSIX:
- raise NotImplementedError("not POSIX")
- s = ""
- uname = os.uname()[2]
- for c in uname:
- if c.isdigit() or c == '.':
- s += c
- else:
- break
- if not s:
- raise ValueError("can't parse %r" % uname)
- minor = 0
- micro = 0
- nums = s.split('.')
- major = int(nums[0])
- if len(nums) >= 2:
- minor = int(nums[1])
- if len(nums) >= 3:
- micro = int(nums[2])
- return (major, minor, micro)
-
-
-def get_winver():
- if not WINDOWS:
- raise NotImplementedError("not WINDOWS")
- wv = sys.getwindowsversion()
- if hasattr(wv, 'service_pack_major'): # python >= 2.7
- sp = wv.service_pack_major or 0
- else:
- r = re.search(r"\s\d$", wv[4])
- if r:
- sp = int(r.group(0))
- else:
- sp = 0
- return (wv[0], wv[1], sp)
-
-
-# ===================================================================
-# --- sync primitives
-# ===================================================================
-
-
-class retry(object):
- """A retry decorator."""
-
- def __init__(self,
- exception=Exception,
- timeout=None,
- retries=None,
- interval=0.001,
- logfun=lambda s: print(s, file=sys.stderr),
- ):
- if timeout and retries:
- raise ValueError("timeout and retries args are mutually exclusive")
- self.exception = exception
- self.timeout = timeout
- self.retries = retries
- self.interval = interval
- self.logfun = logfun
-
- def __iter__(self):
- if self.timeout:
- stop_at = time.time() + self.timeout
- while time.time() < stop_at:
- yield
- elif self.retries:
- for _ in range(self.retries):
- yield
- else:
- while True:
- yield
-
- def sleep(self):
- if self.interval is not None:
- time.sleep(self.interval)
-
- def __call__(self, fun):
- @functools.wraps(fun)
- def wrapper(*args, **kwargs):
- exc = None
- for _ in self:
- try:
- return fun(*args, **kwargs)
- except self.exception as _:
- exc = _
- if self.logfun is not None:
- self.logfun(exc)
- self.sleep()
- continue
- if PY3:
- raise exc
- else:
- raise
-
- # This way the user of the decorated function can change config
- # parameters.
- wrapper.decorator = self
- return wrapper
-
-
-@retry(exception=psutil.NoSuchProcess, logfun=None, timeout=GLOBAL_TIMEOUT,
- interval=0.001)
-def wait_for_pid(pid):
- """Wait for pid to show up in the process list then return.
- Used in the test suite to give time the sub process to initialize.
- """
- psutil.Process(pid)
- if WINDOWS:
- # give it some more time to allow better initialization
- time.sleep(0.01)
-
-
-@retry(exception=(EnvironmentError, AssertionError), logfun=None,
- timeout=GLOBAL_TIMEOUT, interval=0.001)
-def wait_for_file(fname, delete=True, empty=False):
- """Wait for a file to be written on disk with some content."""
- with open(fname, "rb") as f:
- data = f.read()
- if not empty:
- assert data
- if delete:
- safe_rmpath(fname)
- return data
-
-
-@retry(exception=AssertionError, logfun=None, timeout=GLOBAL_TIMEOUT,
- interval=0.001)
-def call_until(fun, expr):
- """Keep calling function for timeout secs and exit if eval()
- expression is True.
- """
- ret = fun()
- assert eval(expr)
- return ret
-
-
-# ===================================================================
-# --- fs
-# ===================================================================
-
-
-def safe_rmpath(path):
- "Convenience function for removing temporary test files or dirs"
- def retry_fun(fun):
- # On Windows it could happen that the file or directory has
- # open handles or references preventing the delete operation
- # to succeed immediately, so we retry for a while. See:
- # https://bugs.python.org/issue33240
- stop_at = time.time() + 1
- while time.time() < stop_at:
- try:
- return fun()
- except WindowsError as _:
- err = _
- if err.errno != errno.ENOENT:
- raise
- else:
- warn("ignoring %s" % (str(err)))
- time.sleep(0.01)
- raise err
-
- try:
- st = os.stat(path)
- if stat.S_ISDIR(st.st_mode):
- fun = functools.partial(shutil.rmtree, path)
- else:
- fun = functools.partial(os.remove, path)
- if POSIX:
- fun()
- else:
- retry_fun(fun)
- except OSError as err:
- if err.errno != errno.ENOENT:
- raise
-
-
-def safe_mkdir(dir):
- "Convenience function for creating a directory"
- try:
- os.mkdir(dir)
- except OSError as err:
- if err.errno != errno.EEXIST:
- raise
-
-
-@contextlib.contextmanager
-def chdir(dirname):
- "Context manager which temporarily changes the current directory."
- curdir = os.getcwd()
- try:
- os.chdir(dirname)
- yield
- finally:
- os.chdir(curdir)
-
-
-def create_exe(outpath, c_code=None):
- """Creates an executable file in the given location."""
- assert not os.path.exists(outpath), outpath
- if c_code:
- if not which("gcc"):
- raise ValueError("gcc is not installed")
- if isinstance(c_code, bool): # c_code is True
- c_code = textwrap.dedent(
- """
- #include
- int main() {
- pause();
- return 1;
- }
- """)
- assert isinstance(c_code, str), c_code
- with tempfile.NamedTemporaryFile(
- suffix='.c', delete=False, mode='wt') as f:
- f.write(c_code)
- try:
- subprocess.check_call(["gcc", f.name, "-o", outpath])
- finally:
- safe_rmpath(f.name)
- else:
- # copy python executable
- shutil.copyfile(PYTHON_EXE, outpath)
- if POSIX:
- st = os.stat(outpath)
- os.chmod(outpath, st.st_mode | stat.S_IEXEC)
-
-
-def unique_filename(prefix=TESTFILE_PREFIX, suffix=""):
- return tempfile.mktemp(prefix=prefix, suffix=suffix)
-
-
-# ===================================================================
-# --- testing
-# ===================================================================
-
-
-class TestCase(unittest.TestCase):
-
- # Print a full path representation of the single unit tests
- # being run.
- def __str__(self):
- return "%s.%s.%s" % (
- self.__class__.__module__, self.__class__.__name__,
- self._testMethodName)
-
- # assertRaisesRegexp renamed to assertRaisesRegex in 3.3;
- # add support for the new name.
- if not hasattr(unittest.TestCase, 'assertRaisesRegex'):
- assertRaisesRegex = unittest.TestCase.assertRaisesRegexp
-
-
-# override default unittest.TestCase
-unittest.TestCase = TestCase
-
-
-def _setup_tests():
- if 'PSUTIL_TESTING' not in os.environ:
- # This won't work on Windows but set_testing() below will do it.
- os.environ['PSUTIL_TESTING'] = '1'
- psutil._psplatform.cext.set_testing()
-
-
-def get_suite():
- testmods = [os.path.splitext(x)[0] for x in os.listdir(HERE)
- if x.endswith('.py') and x.startswith('test_') and not
- x.startswith('test_memory_leaks')]
- if "WHEELHOUSE_UPLOADER_USERNAME" in os.environ:
- testmods = [x for x in testmods if not x.endswith((
- "osx", "posix", "linux"))]
- suite = unittest.TestSuite()
- for tm in testmods:
- # ...so that the full test paths are printed on screen
- tm = "psutil.tests.%s" % tm
- suite.addTest(unittest.defaultTestLoader.loadTestsFromName(tm))
- return suite
-
-
-def run_suite():
- _setup_tests()
- result = unittest.TextTestRunner(verbosity=VERBOSITY).run(get_suite())
- success = result.wasSuccessful()
- sys.exit(0 if success else 1)
-
-
-def run_test_module_by_name(name):
- # testmodules = [os.path.splitext(x)[0] for x in os.listdir(HERE)
- # if x.endswith('.py') and x.startswith('test_')]
- _setup_tests()
- name = os.path.splitext(os.path.basename(name))[0]
- suite = unittest.TestSuite()
- suite.addTest(unittest.defaultTestLoader.loadTestsFromName(name))
- result = unittest.TextTestRunner(verbosity=VERBOSITY).run(suite)
- success = result.wasSuccessful()
- sys.exit(0 if success else 1)
-
-
-def retry_before_failing(retries=NO_RETRIES):
- """Decorator which runs a test function and retries N times before
- actually failing.
- """
- return retry(exception=AssertionError, timeout=None, retries=retries)
-
-
-def skip_on_access_denied(only_if=None):
- """Decorator to Ignore AccessDenied exceptions."""
- def decorator(fun):
- @functools.wraps(fun)
- def wrapper(*args, **kwargs):
- try:
- return fun(*args, **kwargs)
- except psutil.AccessDenied:
- if only_if is not None:
- if not only_if:
- raise
- raise unittest.SkipTest("raises AccessDenied")
- return wrapper
- return decorator
-
-
-def skip_on_not_implemented(only_if=None):
- """Decorator to Ignore NotImplementedError exceptions."""
- def decorator(fun):
- @functools.wraps(fun)
- def wrapper(*args, **kwargs):
- try:
- return fun(*args, **kwargs)
- except NotImplementedError:
- if only_if is not None:
- if not only_if:
- raise
- msg = "%r was skipped because it raised NotImplementedError" \
- % fun.__name__
- raise unittest.SkipTest(msg)
- return wrapper
- return decorator
-
-
-# ===================================================================
-# --- network
-# ===================================================================
-
-
-def get_free_port(host='127.0.0.1'):
- """Return an unused TCP port."""
- with contextlib.closing(socket.socket()) as sock:
- sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
- sock.bind((host, 0))
- return sock.getsockname()[1]
-
-
-@contextlib.contextmanager
-def unix_socket_path(suffix=""):
- """A context manager which returns a non-existent file name
- and tries to delete it on exit.
- """
- assert psutil.POSIX
- path = unique_filename(suffix=suffix)
- try:
- yield path
- finally:
- try:
- os.unlink(path)
- except OSError:
- pass
-
-
-def bind_socket(family=AF_INET, type=SOCK_STREAM, addr=None):
- """Binds a generic socket."""
- if addr is None and family in (AF_INET, AF_INET6):
- addr = ("", 0)
- sock = socket.socket(family, type)
- try:
- sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
- sock.bind(addr)
- if type == socket.SOCK_STREAM:
- sock.listen(10)
- return sock
- except Exception:
- sock.close()
- raise
-
-
-def bind_unix_socket(name, type=socket.SOCK_STREAM):
- """Bind a UNIX socket."""
- assert psutil.POSIX
- assert not os.path.exists(name), name
- sock = socket.socket(socket.AF_UNIX, type)
- try:
- sock.bind(name)
- if type == socket.SOCK_STREAM:
- sock.listen(10)
- except Exception:
- sock.close()
- raise
- return sock
-
-
-def tcp_socketpair(family, addr=("", 0)):
- """Build a pair of TCP sockets connected to each other.
- Return a (server, client) tuple.
- """
- with contextlib.closing(socket.socket(family, SOCK_STREAM)) as ll:
- ll.bind(addr)
- ll.listen(10)
- addr = ll.getsockname()
- c = socket.socket(family, SOCK_STREAM)
- try:
- c.connect(addr)
- caddr = c.getsockname()
- while True:
- a, addr = ll.accept()
- # check that we've got the correct client
- if addr == caddr:
- return (a, c)
- a.close()
- except OSError:
- c.close()
- raise
-
-
-def unix_socketpair(name):
- """Build a pair of UNIX sockets connected to each other through
- the same UNIX file name.
- Return a (server, client) tuple.
- """
- assert psutil.POSIX
- server = client = None
- try:
- server = bind_unix_socket(name, type=socket.SOCK_STREAM)
- server.setblocking(0)
- client = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
- client.setblocking(0)
- client.connect(name)
- # new = server.accept()
- except Exception:
- if server is not None:
- server.close()
- if client is not None:
- client.close()
- raise
- return (server, client)
-
-
-@contextlib.contextmanager
-def create_sockets():
- """Open as many socket families / types as possible."""
- socks = []
- fname1 = fname2 = None
- try:
- socks.append(bind_socket(socket.AF_INET, socket.SOCK_STREAM))
- socks.append(bind_socket(socket.AF_INET, socket.SOCK_DGRAM))
- if supports_ipv6():
- socks.append(bind_socket(socket.AF_INET6, socket.SOCK_STREAM))
- socks.append(bind_socket(socket.AF_INET6, socket.SOCK_DGRAM))
- if POSIX and HAS_CONNECTIONS_UNIX:
- fname1 = unix_socket_path().__enter__()
- fname2 = unix_socket_path().__enter__()
- s1, s2 = unix_socketpair(fname1)
- s3 = bind_unix_socket(fname2, type=socket.SOCK_DGRAM)
- # self.addCleanup(safe_rmpath, fname1)
- # self.addCleanup(safe_rmpath, fname2)
- for s in (s1, s2, s3):
- socks.append(s)
- yield socks
- finally:
- for s in socks:
- s.close()
- if fname1 is not None:
- safe_rmpath(fname1)
- if fname2 is not None:
- safe_rmpath(fname2)
-
-
-def check_net_address(addr, family):
- """Check a net address validity. Supported families are IPv4,
- IPv6 and MAC addresses.
- """
- import ipaddress # python >= 3.3 / requires "pip install ipaddress"
- if enum and PY3:
- assert isinstance(family, enum.IntEnum), family
- if family == socket.AF_INET:
- octs = [int(x) for x in addr.split('.')]
- assert len(octs) == 4, addr
- for num in octs:
- assert 0 <= num <= 255, addr
- if not PY3:
- addr = unicode(addr)
- ipaddress.IPv4Address(addr)
- elif family == socket.AF_INET6:
- assert isinstance(addr, str), addr
- if not PY3:
- addr = unicode(addr)
- ipaddress.IPv6Address(addr)
- elif family == psutil.AF_LINK:
- assert re.match(r'([a-fA-F0-9]{2}[:|\-]?){6}', addr) is not None, addr
- else:
- raise ValueError("unknown family %r", family)
-
-
-def check_connection_ntuple(conn):
- """Check validity of a connection namedtuple."""
- # check ntuple
- assert len(conn) in (6, 7), conn
- has_pid = len(conn) == 7
- has_fd = getattr(conn, 'fd', -1) != -1
- assert conn[0] == conn.fd
- assert conn[1] == conn.family
- assert conn[2] == conn.type
- assert conn[3] == conn.laddr
- assert conn[4] == conn.raddr
- assert conn[5] == conn.status
- if has_pid:
- assert conn[6] == conn.pid
-
- # check fd
- if has_fd:
- assert conn.fd >= 0, conn
- if hasattr(socket, 'fromfd') and not WINDOWS:
- try:
- dupsock = socket.fromfd(conn.fd, conn.family, conn.type)
- except (socket.error, OSError) as err:
- if err.args[0] != errno.EBADF:
- raise
- else:
- with contextlib.closing(dupsock):
- assert dupsock.family == conn.family
- assert dupsock.type == conn.type
-
- # check family
- assert conn.family in (AF_INET, AF_INET6, AF_UNIX), repr(conn.family)
- if conn.family in (AF_INET, AF_INET6):
- # actually try to bind the local socket; ignore IPv6
- # sockets as their address might be represented as
- # an IPv4-mapped-address (e.g. "::127.0.0.1")
- # and that's rejected by bind()
- if conn.family == AF_INET:
- s = socket.socket(conn.family, conn.type)
- with contextlib.closing(s):
- try:
- s.bind((conn.laddr[0], 0))
- except socket.error as err:
- if err.errno != errno.EADDRNOTAVAIL:
- raise
- elif conn.family == AF_UNIX:
- assert conn.status == psutil.CONN_NONE, conn.status
-
- # check type (SOCK_SEQPACKET may happen in case of AF_UNIX socks)
- assert conn.type in (SOCK_STREAM, SOCK_DGRAM, SOCK_SEQPACKET), \
- repr(conn.type)
- if conn.type == SOCK_DGRAM:
- assert conn.status == psutil.CONN_NONE, conn.status
-
- # check laddr (IP address and port sanity)
- for addr in (conn.laddr, conn.raddr):
- if conn.family in (AF_INET, AF_INET6):
- assert isinstance(addr, tuple), addr
- if not addr:
- continue
- assert isinstance(addr.port, int), addr.port
- assert 0 <= addr.port <= 65535, addr.port
- check_net_address(addr.ip, conn.family)
- elif conn.family == AF_UNIX:
- assert isinstance(addr, str), addr
-
- # check status
- assert isinstance(conn.status, str), conn
- valids = [getattr(psutil, x) for x in dir(psutil) if x.startswith('CONN_')]
- assert conn.status in valids, conn
-
-
-# ===================================================================
-# --- compatibility
-# ===================================================================
-
-
-def reload_module(module):
- """Backport of importlib.reload of Python 3.3+."""
- try:
- import importlib
- if not hasattr(importlib, 'reload'): # python <=3.3
- raise ImportError
- except ImportError:
- import imp
- return imp.reload(module)
- else:
- return importlib.reload(module)
-
-
-def import_module_by_path(path):
- name = os.path.splitext(os.path.basename(path))[0]
- if sys.version_info[0] == 2:
- import imp
- return imp.load_source(name, path)
- elif sys.version_info[:2] <= (3, 4):
- from importlib.machinery import SourceFileLoader
- return SourceFileLoader(name, path).load_module()
- else:
- import importlib.util
- spec = importlib.util.spec_from_file_location(name, path)
- mod = importlib.util.module_from_spec(spec)
- spec.loader.exec_module(mod)
- return mod
-
-
-# ===================================================================
-# --- others
-# ===================================================================
-
-
-def warn(msg):
- """Raise a warning msg."""
- warnings.warn(msg, UserWarning)
-
-
-def is_namedtuple(x):
- """Check if object is an instance of namedtuple."""
- t = type(x)
- b = t.__bases__
- if len(b) != 1 or b[0] != tuple:
- return False
- f = getattr(t, '_fields', None)
- if not isinstance(f, tuple):
- return False
- return all(type(n) == str for n in f)
-
-
-if POSIX:
- @contextlib.contextmanager
- def copyload_shared_lib(dst_prefix=TESTFILE_PREFIX):
- """Ctx 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.
- """
- ext = ".so"
- dst = tempfile.mktemp(prefix=dst_prefix, suffix=ext)
- libs = [x.path for x in psutil.Process().memory_maps() if
- os.path.splitext(x.path)[1] == ext and
- 'python' in x.path.lower()]
- src = random.choice(libs)
- shutil.copyfile(src, dst)
- try:
- ctypes.CDLL(dst)
- yield dst
- finally:
- safe_rmpath(dst)
-else:
- @contextlib.contextmanager
- def copyload_shared_lib(dst_prefix=TESTFILE_PREFIX):
- """Ctx 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.
- """
- from ctypes import wintypes
- from ctypes import WinError
- ext = ".dll"
- dst = tempfile.mktemp(prefix=dst_prefix, suffix=ext)
- libs = [x.path for x in psutil.Process().memory_maps() if
- os.path.splitext(x.path)[1].lower() == ext and
- 'python' in os.path.basename(x.path).lower() and
- 'wow64' not in x.path.lower()]
- src = random.choice(libs)
- shutil.copyfile(src, dst)
- cfile = None
- try:
- cfile = ctypes.WinDLL(dst)
- yield dst
- finally:
- # Work around OverflowError:
- # - https://ci.appveyor.com/project/giampaolo/psutil/build/1207/
- # job/o53330pbnri9bcw7
- # - http://bugs.python.org/issue30286
- # - http://stackoverflow.com/questions/23522055
- if cfile is not None:
- FreeLibrary = ctypes.windll.kernel32.FreeLibrary
- FreeLibrary.argtypes = [wintypes.HMODULE]
- ret = FreeLibrary(cfile._handle)
- if ret == 0:
- WinError()
- safe_rmpath(dst)
diff --git a/server/www/packages/packages-darwin/x64/psutil/tests/__main__.py b/server/www/packages/packages-darwin/x64/psutil/tests/__main__.py
deleted file mode 100644
index 36554a1..0000000
--- a/server/www/packages/packages-darwin/x64/psutil/tests/__main__.py
+++ /dev/null
@@ -1,94 +0,0 @@
-#!/usr/bin/env python
-
-# 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.
-
-"""
-Run unit tests. This is invoked by:
-
-$ python -m psutil.tests
-"""
-
-import contextlib
-import optparse
-import os
-import sys
-import tempfile
-try:
- from urllib.request import urlopen # py3
-except ImportError:
- from urllib2 import urlopen
-
-from psutil.tests import PYTHON_EXE
-from psutil.tests import run_suite
-
-
-HERE = os.path.abspath(os.path.dirname(__file__))
-GET_PIP_URL = "https://bootstrap.pypa.io/get-pip.py"
-TEST_DEPS = []
-if sys.version_info[:2] == (2, 6):
- TEST_DEPS.extend(["ipaddress", "unittest2", "argparse", "mock==1.0.1"])
-elif sys.version_info[:2] == (2, 7) or sys.version_info[:2] <= (3, 2):
- TEST_DEPS.extend(["ipaddress", "mock"])
-
-
-def install_pip():
- try:
- import pip # NOQA
- except ImportError:
- import ssl
- f = tempfile.NamedTemporaryFile(suffix='.py')
- with contextlib.closing(f):
- print("downloading %s to %s" % (GET_PIP_URL, f.name))
- if hasattr(ssl, '_create_unverified_context'):
- ctx = ssl._create_unverified_context()
- else:
- ctx = None
- kwargs = dict(context=ctx) if ctx else {}
- req = urlopen(GET_PIP_URL, **kwargs)
- data = req.read()
- f.write(data)
- f.flush()
-
- print("installing pip")
- code = os.system('%s %s --user' % (PYTHON_EXE, f.name))
- return code
-
-
-def install_test_deps(deps=None):
- """Install test dependencies via pip."""
- if deps is None:
- deps = TEST_DEPS
- deps = set(deps)
- if deps:
- is_venv = hasattr(sys, 'real_prefix')
- opts = "--user" if not is_venv else ""
- install_pip()
- code = os.system('%s -m pip install %s --upgrade %s' % (
- PYTHON_EXE, opts, " ".join(deps)))
- return code
-
-
-def main():
- usage = "%s -m psutil.tests [opts]" % PYTHON_EXE
- parser = optparse.OptionParser(usage=usage, description="run unit tests")
- parser.add_option("-i", "--install-deps",
- action="store_true", default=False,
- help="don't print status messages to stdout")
-
- opts, args = parser.parse_args()
- if opts.install_deps:
- install_pip()
- install_test_deps()
- else:
- for dep in TEST_DEPS:
- try:
- __import__(dep.split("==")[0])
- except ImportError:
- sys.exit("%r lib is not installed; run %s -m psutil.tests "
- "--install-deps" % (dep, PYTHON_EXE))
- run_suite()
-
-
-main()
diff --git a/server/www/packages/packages-darwin/x64/psutil/tests/test_aix.py b/server/www/packages/packages-darwin/x64/psutil/tests/test_aix.py
deleted file mode 100644
index 7a8a4c3..0000000
--- a/server/www/packages/packages-darwin/x64/psutil/tests/test_aix.py
+++ /dev/null
@@ -1,121 +0,0 @@
-#!/usr/bin/env python
-
-# Copyright (c) 2009, Giampaolo Rodola'
-# Copyright (c) 2017, Arnon Yaari
-# All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""AIX specific tests."""
-
-import re
-
-from psutil import AIX
-from psutil.tests import run_test_module_by_name
-from psutil.tests import sh
-from psutil.tests import unittest
-import psutil
-
-
-@unittest.skipIf(not AIX, "AIX only")
-class AIXSpecificTestCase(unittest.TestCase):
-
- def test_virtual_memory(self):
- out = sh('/usr/bin/svmon -O unit=KB')
- re_pattern = "memory\s*"
- for field in ("size inuse free pin virtual available mmode").split():
- re_pattern += "(?P<%s>\S+)\s+" % (field,)
- matchobj = re.search(re_pattern, out)
-
- self.assertIsNotNone(
- matchobj, "svmon command returned unexpected output")
-
- KB = 1024
- total = int(matchobj.group("size")) * KB
- available = int(matchobj.group("available")) * KB
- used = int(matchobj.group("inuse")) * KB
- free = int(matchobj.group("free")) * KB
-
- psutil_result = psutil.virtual_memory()
-
- # MEMORY_TOLERANCE from psutil.tests is not enough. For some reason
- # we're seeing differences of ~1.2 MB. 2 MB is still a good tolerance
- # when compared to GBs.
- MEMORY_TOLERANCE = 2 * KB * KB # 2 MB
- self.assertEqual(psutil_result.total, total)
- self.assertAlmostEqual(
- psutil_result.used, used, delta=MEMORY_TOLERANCE)
- self.assertAlmostEqual(
- psutil_result.available, available, delta=MEMORY_TOLERANCE)
- self.assertAlmostEqual(
- psutil_result.free, free, delta=MEMORY_TOLERANCE)
-
- def test_swap_memory(self):
- out = sh('/usr/sbin/lsps -a')
- # From the man page, "The size is given in megabytes" so we assume
- # we'll always have 'MB' in the result
- # TODO maybe try to use "swap -l" to check "used" too, but its units
- # are not guaranteed to be "MB" so parsing may not be consistent
- matchobj = re.search("(?P\S+)\s+"
- "(?P\S+)\s+"
- "(?P\S+)\s+"
- "(?P\d+)MB", out)
-
- self.assertIsNotNone(
- matchobj, "lsps command returned unexpected output")
-
- total_mb = int(matchobj.group("size"))
- MB = 1024 ** 2
- psutil_result = psutil.swap_memory()
- # we divide our result by MB instead of multiplying the lsps value by
- # MB because lsps may round down, so we round down too
- self.assertEqual(int(psutil_result.total / MB), total_mb)
-
- def test_cpu_stats(self):
- out = sh('/usr/bin/mpstat -a')
-
- re_pattern = "ALL\s*"
- for field in ("min maj mpcs mpcr dev soft dec ph cs ics bound rq "
- "push S3pull S3grd S0rd S1rd S2rd S3rd S4rd S5rd "
- "sysc").split():
- re_pattern += "(?P<%s>\S+)\s+" % (field,)
- matchobj = re.search(re_pattern, out)
-
- self.assertIsNotNone(
- matchobj, "mpstat command returned unexpected output")
-
- # numbers are usually in the millions so 1000 is ok for tolerance
- CPU_STATS_TOLERANCE = 1000
- psutil_result = psutil.cpu_stats()
- self.assertAlmostEqual(
- psutil_result.ctx_switches,
- int(matchobj.group("cs")),
- delta=CPU_STATS_TOLERANCE)
- self.assertAlmostEqual(
- psutil_result.syscalls,
- int(matchobj.group("sysc")),
- delta=CPU_STATS_TOLERANCE)
- self.assertAlmostEqual(
- psutil_result.interrupts,
- int(matchobj.group("dev")),
- delta=CPU_STATS_TOLERANCE)
- self.assertAlmostEqual(
- psutil_result.soft_interrupts,
- int(matchobj.group("soft")),
- delta=CPU_STATS_TOLERANCE)
-
- def test_cpu_count_logical(self):
- out = sh('/usr/bin/mpstat -a')
- mpstat_lcpu = int(re.search("lcpu=(\d+)", out).group(1))
- psutil_lcpu = psutil.cpu_count(logical=True)
- self.assertEqual(mpstat_lcpu, psutil_lcpu)
-
- def test_net_if_addrs_names(self):
- out = sh('/etc/ifconfig -l')
- ifconfig_names = set(out.split())
- psutil_names = set(psutil.net_if_addrs().keys())
- self.assertSetEqual(ifconfig_names, psutil_names)
-
-
-if __name__ == '__main__':
- run_test_module_by_name(__file__)
diff --git a/server/www/packages/packages-darwin/x64/psutil/tests/test_bsd.py b/server/www/packages/packages-darwin/x64/psutil/tests/test_bsd.py
deleted file mode 100644
index 7846c1c..0000000
--- a/server/www/packages/packages-darwin/x64/psutil/tests/test_bsd.py
+++ /dev/null
@@ -1,519 +0,0 @@
-#!/usr/bin/env python
-
-# 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.
-
-# TODO: (FreeBSD) add test for comparing connections with 'sockstat' cmd.
-
-
-"""Tests specific to all BSD platforms."""
-
-
-import datetime
-import os
-import re
-import time
-
-import psutil
-from psutil import BSD
-from psutil import FREEBSD
-from psutil import NETBSD
-from psutil import OPENBSD
-from psutil.tests import get_test_subprocess
-from psutil.tests import HAS_BATTERY
-from psutil.tests import MEMORY_TOLERANCE
-from psutil.tests import reap_children
-from psutil.tests import retry_before_failing
-from psutil.tests import run_test_module_by_name
-from psutil.tests import sh
-from psutil.tests import unittest
-from psutil.tests import which
-
-
-if BSD:
- PAGESIZE = os.sysconf("SC_PAGE_SIZE")
- if os.getuid() == 0: # muse requires root privileges
- MUSE_AVAILABLE = which('muse')
- else:
- MUSE_AVAILABLE = False
-else:
- MUSE_AVAILABLE = False
-
-
-def sysctl(cmdline):
- """Expects a sysctl command with an argument and parse the result
- returning only the value of interest.
- """
- result = sh("sysctl " + cmdline)
- if FREEBSD:
- result = result[result.find(": ") + 2:]
- elif OPENBSD or NETBSD:
- result = result[result.find("=") + 1:]
- try:
- return int(result)
- except ValueError:
- return result
-
-
-def muse(field):
- """Thin wrapper around 'muse' cmdline utility."""
- out = sh('muse')
- for line in out.split('\n'):
- if line.startswith(field):
- break
- else:
- raise ValueError("line not found")
- return int(line.split()[1])
-
-
-# =====================================================================
-# --- All BSD*
-# =====================================================================
-
-
-@unittest.skipIf(not BSD, "BSD only")
-class BSDSpecificTestCase(unittest.TestCase):
- """Generic tests common to all BSD variants."""
-
- @classmethod
- def setUpClass(cls):
- cls.pid = get_test_subprocess().pid
-
- @classmethod
- def tearDownClass(cls):
- reap_children()
-
- @unittest.skipIf(NETBSD, "-o lstart doesn't work on NETBSD")
- def test_process_create_time(self):
- output = sh("ps -o lstart -p %s" % self.pid)
- start_ps = output.replace('STARTED', '').strip()
- start_psutil = psutil.Process(self.pid).create_time()
- start_psutil = time.strftime("%a %b %e %H:%M:%S %Y",
- time.localtime(start_psutil))
- self.assertEqual(start_ps, start_psutil)
-
- def test_disks(self):
- # test psutil.disk_usage() and psutil.disk_partitions()
- # against "df -a"
- def df(path):
- out = sh('df -k "%s"' % path).strip()
- lines = out.split('\n')
- lines.pop(0)
- line = lines.pop(0)
- dev, total, used, free = line.split()[:4]
- if dev == 'none':
- dev = ''
- total = int(total) * 1024
- used = int(used) * 1024
- free = int(free) * 1024
- return dev, total, used, free
-
- for part in psutil.disk_partitions(all=False):
- usage = psutil.disk_usage(part.mountpoint)
- dev, total, used, free = df(part.mountpoint)
- self.assertEqual(part.device, dev)
- self.assertEqual(usage.total, total)
- # 10 MB tollerance
- if abs(usage.free - free) > 10 * 1024 * 1024:
- self.fail("psutil=%s, df=%s" % (usage.free, free))
- if abs(usage.used - used) > 10 * 1024 * 1024:
- self.fail("psutil=%s, df=%s" % (usage.used, used))
-
- @unittest.skipIf(not which('sysctl'), "sysctl cmd not available")
- def test_cpu_count_logical(self):
- syst = sysctl("hw.ncpu")
- self.assertEqual(psutil.cpu_count(logical=True), syst)
-
- @unittest.skipIf(not which('sysctl'), "sysctl cmd not available")
- def test_virtual_memory_total(self):
- num = sysctl('hw.physmem')
- self.assertEqual(num, psutil.virtual_memory().total)
-
- def test_net_if_stats(self):
- for name, stats in psutil.net_if_stats().items():
- try:
- out = sh("ifconfig %s" % name)
- except RuntimeError:
- pass
- else:
- self.assertEqual(stats.isup, 'RUNNING' in out, msg=out)
- if "mtu" in out:
- self.assertEqual(stats.mtu,
- int(re.findall(r'mtu (\d+)', out)[0]))
-
-
-# =====================================================================
-# --- FreeBSD
-# =====================================================================
-
-
-@unittest.skipIf(not FREEBSD, "FREEBSD only")
-class FreeBSDSpecificTestCase(unittest.TestCase):
-
- @classmethod
- def setUpClass(cls):
- cls.pid = get_test_subprocess().pid
-
- @classmethod
- def tearDownClass(cls):
- reap_children()
-
- @staticmethod
- def parse_swapinfo():
- # the last line is always the total
- output = sh("swapinfo -k").splitlines()[-1]
- parts = re.split(r'\s+', output)
-
- if not parts:
- raise ValueError("Can't parse swapinfo: %s" % output)
-
- # the size is in 1k units, so multiply by 1024
- total, used, free = (int(p) * 1024 for p in parts[1:4])
- return total, used, free
-
- @retry_before_failing()
- def test_proc_memory_maps(self):
- out = sh('procstat -v %s' % self.pid)
- maps = psutil.Process(self.pid).memory_maps(grouped=False)
- lines = out.split('\n')[1:]
- while lines:
- line = lines.pop()
- fields = line.split()
- _, start, stop, perms, res = fields[:5]
- map = maps.pop()
- self.assertEqual("%s-%s" % (start, stop), map.addr)
- self.assertEqual(int(res), map.rss)
- if not map.path.startswith('['):
- self.assertEqual(fields[10], map.path)
-
- def test_proc_exe(self):
- out = sh('procstat -b %s' % self.pid)
- self.assertEqual(psutil.Process(self.pid).exe(),
- out.split('\n')[1].split()[-1])
-
- def test_proc_cmdline(self):
- out = sh('procstat -c %s' % self.pid)
- self.assertEqual(' '.join(psutil.Process(self.pid).cmdline()),
- ' '.join(out.split('\n')[1].split()[2:]))
-
- def test_proc_uids_gids(self):
- out = sh('procstat -s %s' % self.pid)
- euid, ruid, suid, egid, rgid, sgid = out.split('\n')[1].split()[2:8]
- p = psutil.Process(self.pid)
- uids = p.uids()
- gids = p.gids()
- self.assertEqual(uids.real, int(ruid))
- self.assertEqual(uids.effective, int(euid))
- self.assertEqual(uids.saved, int(suid))
- self.assertEqual(gids.real, int(rgid))
- self.assertEqual(gids.effective, int(egid))
- self.assertEqual(gids.saved, int(sgid))
-
- @retry_before_failing()
- def test_proc_ctx_switches(self):
- tested = []
- out = sh('procstat -r %s' % self.pid)
- p = psutil.Process(self.pid)
- for line in out.split('\n'):
- line = line.lower().strip()
- if ' voluntary context' in line:
- pstat_value = int(line.split()[-1])
- psutil_value = p.num_ctx_switches().voluntary
- self.assertEqual(pstat_value, psutil_value)
- tested.append(None)
- elif ' involuntary context' in line:
- pstat_value = int(line.split()[-1])
- psutil_value = p.num_ctx_switches().involuntary
- self.assertEqual(pstat_value, psutil_value)
- tested.append(None)
- if len(tested) != 2:
- raise RuntimeError("couldn't find lines match in procstat out")
-
- @retry_before_failing()
- def test_proc_cpu_times(self):
- tested = []
- out = sh('procstat -r %s' % self.pid)
- p = psutil.Process(self.pid)
- for line in out.split('\n'):
- line = line.lower().strip()
- if 'user time' in line:
- pstat_value = float('0.' + line.split()[-1].split('.')[-1])
- psutil_value = p.cpu_times().user
- self.assertEqual(pstat_value, psutil_value)
- tested.append(None)
- elif 'system time' in line:
- pstat_value = float('0.' + line.split()[-1].split('.')[-1])
- psutil_value = p.cpu_times().system
- self.assertEqual(pstat_value, psutil_value)
- tested.append(None)
- if len(tested) != 2:
- raise RuntimeError("couldn't find lines match in procstat out")
-
- # --- virtual_memory(); tests against sysctl
-
- @retry_before_failing()
- def test_vmem_active(self):
- syst = sysctl("vm.stats.vm.v_active_count") * PAGESIZE
- self.assertAlmostEqual(psutil.virtual_memory().active, syst,
- delta=MEMORY_TOLERANCE)
-
- @retry_before_failing()
- def test_vmem_inactive(self):
- syst = sysctl("vm.stats.vm.v_inactive_count") * PAGESIZE
- self.assertAlmostEqual(psutil.virtual_memory().inactive, syst,
- delta=MEMORY_TOLERANCE)
-
- @retry_before_failing()
- def test_vmem_wired(self):
- syst = sysctl("vm.stats.vm.v_wire_count") * PAGESIZE
- self.assertAlmostEqual(psutil.virtual_memory().wired, syst,
- delta=MEMORY_TOLERANCE)
-
- @retry_before_failing()
- def test_vmem_cached(self):
- syst = sysctl("vm.stats.vm.v_cache_count") * PAGESIZE
- self.assertAlmostEqual(psutil.virtual_memory().cached, syst,
- delta=MEMORY_TOLERANCE)
-
- @retry_before_failing()
- def test_vmem_free(self):
- syst = sysctl("vm.stats.vm.v_free_count") * PAGESIZE
- self.assertAlmostEqual(psutil.virtual_memory().free, syst,
- delta=MEMORY_TOLERANCE)
-
- @retry_before_failing()
- def test_vmem_buffers(self):
- syst = sysctl("vfs.bufspace")
- self.assertAlmostEqual(psutil.virtual_memory().buffers, syst,
- delta=MEMORY_TOLERANCE)
-
- # --- virtual_memory(); tests against muse
-
- @unittest.skipIf(not MUSE_AVAILABLE, "muse not installed")
- def test_muse_vmem_total(self):
- num = muse('Total')
- self.assertEqual(psutil.virtual_memory().total, num)
-
- @unittest.skipIf(not MUSE_AVAILABLE, "muse not installed")
- @retry_before_failing()
- def test_muse_vmem_active(self):
- num = muse('Active')
- self.assertAlmostEqual(psutil.virtual_memory().active, num,
- delta=MEMORY_TOLERANCE)
-
- @unittest.skipIf(not MUSE_AVAILABLE, "muse not installed")
- @retry_before_failing()
- def test_muse_vmem_inactive(self):
- num = muse('Inactive')
- self.assertAlmostEqual(psutil.virtual_memory().inactive, num,
- delta=MEMORY_TOLERANCE)
-
- @unittest.skipIf(not MUSE_AVAILABLE, "muse not installed")
- @retry_before_failing()
- def test_muse_vmem_wired(self):
- num = muse('Wired')
- self.assertAlmostEqual(psutil.virtual_memory().wired, num,
- delta=MEMORY_TOLERANCE)
-
- @unittest.skipIf(not MUSE_AVAILABLE, "muse not installed")
- @retry_before_failing()
- def test_muse_vmem_cached(self):
- num = muse('Cache')
- self.assertAlmostEqual(psutil.virtual_memory().cached, num,
- delta=MEMORY_TOLERANCE)
-
- @unittest.skipIf(not MUSE_AVAILABLE, "muse not installed")
- @retry_before_failing()
- def test_muse_vmem_free(self):
- num = muse('Free')
- self.assertAlmostEqual(psutil.virtual_memory().free, num,
- delta=MEMORY_TOLERANCE)
-
- @unittest.skipIf(not MUSE_AVAILABLE, "muse not installed")
- @retry_before_failing()
- def test_muse_vmem_buffers(self):
- num = muse('Buffer')
- self.assertAlmostEqual(psutil.virtual_memory().buffers, num,
- delta=MEMORY_TOLERANCE)
-
- def test_cpu_stats_ctx_switches(self):
- self.assertAlmostEqual(psutil.cpu_stats().ctx_switches,
- sysctl('vm.stats.sys.v_swtch'), delta=1000)
-
- def test_cpu_stats_interrupts(self):
- self.assertAlmostEqual(psutil.cpu_stats().interrupts,
- sysctl('vm.stats.sys.v_intr'), delta=1000)
-
- def test_cpu_stats_soft_interrupts(self):
- self.assertAlmostEqual(psutil.cpu_stats().soft_interrupts,
- sysctl('vm.stats.sys.v_soft'), delta=1000)
-
- def test_cpu_stats_syscalls(self):
- self.assertAlmostEqual(psutil.cpu_stats().syscalls,
- sysctl('vm.stats.sys.v_syscall'), delta=1000)
-
- # def test_cpu_stats_traps(self):
- # self.assertAlmostEqual(psutil.cpu_stats().traps,
- # sysctl('vm.stats.sys.v_trap'), delta=1000)
-
- # --- swap memory
-
- def test_swapmem_free(self):
- total, used, free = self.parse_swapinfo()
- self.assertAlmostEqual(
- psutil.swap_memory().free, free, delta=MEMORY_TOLERANCE)
-
- def test_swapmem_used(self):
- total, used, free = self.parse_swapinfo()
- self.assertAlmostEqual(
- psutil.swap_memory().used, used, delta=MEMORY_TOLERANCE)
-
- def test_swapmem_total(self):
- total, used, free = self.parse_swapinfo()
- self.assertAlmostEqual(
- psutil.swap_memory().total, total, delta=MEMORY_TOLERANCE)
-
- # --- others
-
- def test_boot_time(self):
- s = sysctl('sysctl kern.boottime')
- s = s[s.find(" sec = ") + 7:]
- s = s[:s.find(',')]
- btime = int(s)
- self.assertEqual(btime, psutil.boot_time())
-
- # --- sensors_battery
-
- @unittest.skipIf(not HAS_BATTERY, "no battery")
- def test_sensors_battery(self):
- def secs2hours(secs):
- m, s = divmod(secs, 60)
- h, m = divmod(m, 60)
- return "%d:%02d" % (h, m)
-
- out = sh("acpiconf -i 0")
- fields = dict([(x.split('\t')[0], x.split('\t')[-1])
- for x in out.split("\n")])
- metrics = psutil.sensors_battery()
- percent = int(fields['Remaining capacity:'].replace('%', ''))
- remaining_time = fields['Remaining time:']
- self.assertEqual(metrics.percent, percent)
- if remaining_time == 'unknown':
- self.assertEqual(metrics.secsleft, psutil.POWER_TIME_UNLIMITED)
- else:
- self.assertEqual(secs2hours(metrics.secsleft), remaining_time)
-
- @unittest.skipIf(not HAS_BATTERY, "no battery")
- def test_sensors_battery_against_sysctl(self):
- self.assertEqual(psutil.sensors_battery().percent,
- sysctl("hw.acpi.battery.life"))
- self.assertEqual(psutil.sensors_battery().power_plugged,
- sysctl("hw.acpi.acline") == 1)
- secsleft = psutil.sensors_battery().secsleft
- if secsleft < 0:
- self.assertEqual(sysctl("hw.acpi.battery.time"), -1)
- else:
- self.assertEqual(secsleft, sysctl("hw.acpi.battery.time") * 60)
-
- @unittest.skipIf(HAS_BATTERY, "has battery")
- def test_sensors_battery_no_battery(self):
- # If no battery is present one of these calls is supposed
- # to fail, see:
- # https://github.com/giampaolo/psutil/issues/1074
- with self.assertRaises(RuntimeError):
- sysctl("hw.acpi.battery.life")
- sysctl("hw.acpi.battery.time")
- sysctl("hw.acpi.acline")
- self.assertIsNone(psutil.sensors_battery())
-
-
-# =====================================================================
-# --- OpenBSD
-# =====================================================================
-
-
-@unittest.skipIf(not OPENBSD, "OPENBSD only")
-class OpenBSDSpecificTestCase(unittest.TestCase):
-
- def test_boot_time(self):
- s = sysctl('kern.boottime')
- sys_bt = datetime.datetime.strptime(s, "%a %b %d %H:%M:%S %Y")
- psutil_bt = datetime.datetime.fromtimestamp(psutil.boot_time())
- self.assertEqual(sys_bt, psutil_bt)
-
-
-# =====================================================================
-# --- NetBSD
-# =====================================================================
-
-
-@unittest.skipIf(not NETBSD, "NETBSD only")
-class NetBSDSpecificTestCase(unittest.TestCase):
-
- @staticmethod
- def parse_meminfo(look_for):
- with open('/proc/meminfo', 'rb') as f:
- for line in f:
- if line.startswith(look_for):
- return int(line.split()[1]) * 1024
- raise ValueError("can't find %s" % look_for)
-
- def test_vmem_total(self):
- self.assertEqual(
- psutil.virtual_memory().total, self.parse_meminfo("MemTotal:"))
-
- def test_vmem_free(self):
- self.assertAlmostEqual(
- psutil.virtual_memory().free, self.parse_meminfo("MemFree:"),
- delta=MEMORY_TOLERANCE)
-
- def test_vmem_buffers(self):
- self.assertAlmostEqual(
- psutil.virtual_memory().buffers, self.parse_meminfo("Buffers:"),
- delta=MEMORY_TOLERANCE)
-
- def test_vmem_shared(self):
- self.assertAlmostEqual(
- psutil.virtual_memory().shared, self.parse_meminfo("MemShared:"),
- delta=MEMORY_TOLERANCE)
-
- def test_swapmem_total(self):
- self.assertAlmostEqual(
- psutil.swap_memory().total, self.parse_meminfo("SwapTotal:"),
- delta=MEMORY_TOLERANCE)
-
- def test_swapmem_free(self):
- self.assertAlmostEqual(
- psutil.swap_memory().free, self.parse_meminfo("SwapFree:"),
- delta=MEMORY_TOLERANCE)
-
- def test_swapmem_used(self):
- smem = psutil.swap_memory()
- self.assertEqual(smem.used, smem.total - smem.free)
-
- def test_cpu_stats_interrupts(self):
- with open('/proc/stat', 'rb') as f:
- for line in f:
- if line.startswith(b'intr'):
- interrupts = int(line.split()[1])
- break
- else:
- raise ValueError("couldn't find line")
- self.assertAlmostEqual(
- psutil.cpu_stats().interrupts, interrupts, delta=1000)
-
- def test_cpu_stats_ctx_switches(self):
- with open('/proc/stat', 'rb') as f:
- for line in f:
- if line.startswith(b'ctxt'):
- ctx_switches = int(line.split()[1])
- break
- else:
- raise ValueError("couldn't find line")
- self.assertAlmostEqual(
- psutil.cpu_stats().ctx_switches, ctx_switches, delta=1000)
-
-
-if __name__ == '__main__':
- run_test_module_by_name(__file__)
diff --git a/server/www/packages/packages-darwin/x64/psutil/tests/test_connections.py b/server/www/packages/packages-darwin/x64/psutil/tests/test_connections.py
deleted file mode 100644
index cba835e..0000000
--- a/server/www/packages/packages-darwin/x64/psutil/tests/test_connections.py
+++ /dev/null
@@ -1,525 +0,0 @@
-#!/usr/bin/env python
-
-# 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.
-
-"""Tests for net_connections() and Process.connections() APIs."""
-
-import os
-import socket
-import textwrap
-from contextlib import closing
-from socket import AF_INET
-from socket import AF_INET6
-from socket import SOCK_DGRAM
-from socket import SOCK_STREAM
-
-import psutil
-from psutil import FREEBSD
-from psutil import LINUX
-from psutil import MACOS
-from psutil import NETBSD
-from psutil import OPENBSD
-from psutil import POSIX
-from psutil import SUNOS
-from psutil import WINDOWS
-from psutil._common import supports_ipv6
-from psutil._compat import PY3
-from psutil.tests import AF_UNIX
-from psutil.tests import bind_socket
-from psutil.tests import bind_unix_socket
-from psutil.tests import check_connection_ntuple
-from psutil.tests import create_sockets
-from psutil.tests import get_free_port
-from psutil.tests import HAS_CONNECTIONS_UNIX
-from psutil.tests import pyrun
-from psutil.tests import reap_children
-from psutil.tests import run_test_module_by_name
-from psutil.tests import safe_rmpath
-from psutil.tests import skip_on_access_denied
-from psutil.tests import tcp_socketpair
-from psutil.tests import TESTFN
-from psutil.tests import TRAVIS
-from psutil.tests import unittest
-from psutil.tests import unix_socket_path
-from psutil.tests import unix_socketpair
-from psutil.tests import wait_for_file
-
-
-thisproc = psutil.Process()
-
-
-class Base(object):
-
- def setUp(self):
- if not NETBSD:
- # NetBSD opens a UNIX socket to /var/log/run.
- cons = thisproc.connections(kind='all')
- assert not cons, cons
-
- def tearDown(self):
- safe_rmpath(TESTFN)
- reap_children()
- if not NETBSD:
- # Make sure we closed all resources.
- # NetBSD opens a UNIX socket to /var/log/run.
- cons = thisproc.connections(kind='all')
- assert not cons, cons
-
- def get_conn_from_sock(self, sock):
- cons = thisproc.connections(kind='all')
- smap = dict([(c.fd, c) for c in cons])
- if NETBSD:
- # NetBSD opens a UNIX socket to /var/log/run
- # so there may be more connections.
- return smap[sock.fileno()]
- else:
- self.assertEqual(len(cons), 1)
- if cons[0].fd != -1:
- self.assertEqual(smap[sock.fileno()].fd, sock.fileno())
- return cons[0]
-
- def check_socket(self, sock, conn=None):
- """Given a socket, makes sure it matches the one obtained
- via psutil. It assumes this process created one connection
- only (the one supposed to be checked).
- """
- if conn is None:
- conn = self.get_conn_from_sock(sock)
- check_connection_ntuple(conn)
-
- # fd, family, type
- if conn.fd != -1:
- self.assertEqual(conn.fd, sock.fileno())
- self.assertEqual(conn.family, sock.family)
- # see: http://bugs.python.org/issue30204
- self.assertEqual(
- conn.type, sock.getsockopt(socket.SOL_SOCKET, socket.SO_TYPE))
-
- # local address
- laddr = sock.getsockname()
- if not laddr and PY3 and isinstance(laddr, bytes):
- # See: http://bugs.python.org/issue30205
- laddr = laddr.decode()
- if sock.family == AF_INET6:
- laddr = laddr[:2]
- if sock.family == AF_UNIX and OPENBSD:
- # No addresses are set for UNIX sockets on OpenBSD.
- pass
- else:
- self.assertEqual(conn.laddr, laddr)
-
- # XXX Solaris can't retrieve system-wide UNIX sockets
- if sock.family == AF_UNIX and HAS_CONNECTIONS_UNIX:
- cons = thisproc.connections(kind='all')
- self.compare_procsys_connections(os.getpid(), cons)
- return conn
-
- def compare_procsys_connections(self, pid, proc_cons, kind='all'):
- """Given a process PID and its list of connections compare
- those against system-wide connections retrieved via
- psutil.net_connections.
- """
- try:
- sys_cons = psutil.net_connections(kind=kind)
- except psutil.AccessDenied:
- # On MACOS, system-wide connections are retrieved by iterating
- # over all processes
- if MACOS:
- return
- else:
- raise
- # Filter for this proc PID and exlucde PIDs from the tuple.
- sys_cons = [c[:-1] for c in sys_cons if c.pid == pid]
- sys_cons.sort()
- proc_cons.sort()
- self.assertEqual(proc_cons, sys_cons)
-
-
-# =====================================================================
-# --- Test unconnected sockets
-# =====================================================================
-
-
-class TestUnconnectedSockets(Base, unittest.TestCase):
- """Tests sockets which are open but not connected to anything."""
-
- def test_tcp_v4(self):
- addr = ("127.0.0.1", get_free_port())
- with closing(bind_socket(AF_INET, SOCK_STREAM, addr=addr)) as sock:
- conn = self.check_socket(sock)
- assert not conn.raddr
- self.assertEqual(conn.status, psutil.CONN_LISTEN)
-
- @unittest.skipIf(not supports_ipv6(), "IPv6 not supported")
- def test_tcp_v6(self):
- addr = ("::1", get_free_port())
- with closing(bind_socket(AF_INET6, SOCK_STREAM, addr=addr)) as sock:
- conn = self.check_socket(sock)
- assert not conn.raddr
- self.assertEqual(conn.status, psutil.CONN_LISTEN)
-
- def test_udp_v4(self):
- addr = ("127.0.0.1", get_free_port())
- with closing(bind_socket(AF_INET, SOCK_DGRAM, addr=addr)) as sock:
- conn = self.check_socket(sock)
- assert not conn.raddr
- self.assertEqual(conn.status, psutil.CONN_NONE)
-
- @unittest.skipIf(not supports_ipv6(), "IPv6 not supported")
- def test_udp_v6(self):
- addr = ("::1", get_free_port())
- with closing(bind_socket(AF_INET6, SOCK_DGRAM, addr=addr)) as sock:
- conn = self.check_socket(sock)
- assert not conn.raddr
- self.assertEqual(conn.status, psutil.CONN_NONE)
-
- @unittest.skipIf(not POSIX, 'POSIX only')
- def test_unix_tcp(self):
- with unix_socket_path() as name:
- with closing(bind_unix_socket(name, type=SOCK_STREAM)) as sock:
- conn = self.check_socket(sock)
- assert not conn.raddr
- self.assertEqual(conn.status, psutil.CONN_NONE)
-
- @unittest.skipIf(not POSIX, 'POSIX only')
- def test_unix_udp(self):
- with unix_socket_path() as name:
- with closing(bind_unix_socket(name, type=SOCK_STREAM)) as sock:
- conn = self.check_socket(sock)
- assert not conn.raddr
- self.assertEqual(conn.status, psutil.CONN_NONE)
-
-
-# =====================================================================
-# --- Test connected sockets
-# =====================================================================
-
-
-class TestConnectedSocketPairs(Base, unittest.TestCase):
- """Test socket pairs which are are actually connected to
- each other.
- """
-
- # On SunOS, even after we close() it, the server socket stays around
- # in TIME_WAIT state.
- @unittest.skipIf(SUNOS, "unreliable on SUONS")
- def test_tcp(self):
- addr = ("127.0.0.1", get_free_port())
- assert not thisproc.connections(kind='tcp4')
- server, client = tcp_socketpair(AF_INET, addr=addr)
- try:
- cons = thisproc.connections(kind='tcp4')
- self.assertEqual(len(cons), 2)
- self.assertEqual(cons[0].status, psutil.CONN_ESTABLISHED)
- self.assertEqual(cons[1].status, psutil.CONN_ESTABLISHED)
- # May not be fast enough to change state so it stays
- # commenteed.
- # client.close()
- # cons = thisproc.connections(kind='all')
- # self.assertEqual(len(cons), 1)
- # self.assertEqual(cons[0].status, psutil.CONN_CLOSE_WAIT)
- finally:
- server.close()
- client.close()
-
- @unittest.skipIf(not POSIX, 'POSIX only')
- def test_unix(self):
- with unix_socket_path() as name:
- server, client = unix_socketpair(name)
- try:
- cons = thisproc.connections(kind='unix')
- assert not (cons[0].laddr and cons[0].raddr)
- assert not (cons[1].laddr and cons[1].raddr)
- if NETBSD:
- # On NetBSD creating a UNIX socket will cause
- # a UNIX connection to /var/run/log.
- cons = [c for c in cons if c.raddr != '/var/run/log']
- self.assertEqual(len(cons), 2)
- if LINUX or FREEBSD or SUNOS:
- # remote path is never set
- self.assertEqual(cons[0].raddr, "")
- self.assertEqual(cons[1].raddr, "")
- # one local address should though
- self.assertEqual(name, cons[0].laddr or cons[1].laddr)
- elif OPENBSD:
- # No addresses whatsoever here.
- for addr in (cons[0].laddr, cons[0].raddr,
- cons[1].laddr, cons[1].raddr):
- self.assertEqual(addr, "")
- else:
- # On other systems either the laddr or raddr
- # of both peers are set.
- self.assertEqual(cons[0].laddr or cons[1].laddr, name)
- self.assertEqual(cons[0].raddr or cons[1].raddr, name)
- finally:
- server.close()
- client.close()
-
- @skip_on_access_denied(only_if=MACOS)
- def test_combos(self):
- def check_conn(proc, conn, family, type, laddr, raddr, status, kinds):
- all_kinds = ("all", "inet", "inet4", "inet6", "tcp", "tcp4",
- "tcp6", "udp", "udp4", "udp6")
- check_connection_ntuple(conn)
- self.assertEqual(conn.family, family)
- self.assertEqual(conn.type, type)
- self.assertEqual(conn.laddr, laddr)
- self.assertEqual(conn.raddr, raddr)
- self.assertEqual(conn.status, status)
- for kind in all_kinds:
- cons = proc.connections(kind=kind)
- if kind in kinds:
- assert cons
- else:
- assert not cons, cons
- # compare against system-wide connections
- # XXX Solaris can't retrieve system-wide UNIX
- # sockets.
- if HAS_CONNECTIONS_UNIX:
- self.compare_procsys_connections(proc.pid, [conn])
-
- tcp_template = textwrap.dedent("""
- import socket, time
- s = socket.socket($family, socket.SOCK_STREAM)
- s.bind(('$addr', 0))
- s.listen(1)
- with open('$testfn', 'w') as f:
- f.write(str(s.getsockname()[:2]))
- time.sleep(60)
- """)
-
- udp_template = textwrap.dedent("""
- import socket, time
- s = socket.socket($family, socket.SOCK_DGRAM)
- s.bind(('$addr', 0))
- with open('$testfn', 'w') as f:
- f.write(str(s.getsockname()[:2]))
- time.sleep(60)
- """)
-
- from string import Template
- testfile = os.path.basename(TESTFN)
- tcp4_template = Template(tcp_template).substitute(
- family=int(AF_INET), addr="127.0.0.1", testfn=testfile)
- udp4_template = Template(udp_template).substitute(
- family=int(AF_INET), addr="127.0.0.1", testfn=testfile)
- tcp6_template = Template(tcp_template).substitute(
- family=int(AF_INET6), addr="::1", testfn=testfile)
- udp6_template = Template(udp_template).substitute(
- family=int(AF_INET6), addr="::1", testfn=testfile)
-
- # launch various subprocess instantiating a socket of various
- # families and types to enrich psutil results
- tcp4_proc = pyrun(tcp4_template)
- tcp4_addr = eval(wait_for_file(testfile))
- udp4_proc = pyrun(udp4_template)
- udp4_addr = eval(wait_for_file(testfile))
- if supports_ipv6():
- tcp6_proc = pyrun(tcp6_template)
- tcp6_addr = eval(wait_for_file(testfile))
- udp6_proc = pyrun(udp6_template)
- udp6_addr = eval(wait_for_file(testfile))
- else:
- tcp6_proc = None
- udp6_proc = None
- tcp6_addr = None
- udp6_addr = None
-
- for p in thisproc.children():
- cons = p.connections()
- self.assertEqual(len(cons), 1)
- for conn in cons:
- # TCP v4
- if p.pid == tcp4_proc.pid:
- check_conn(p, conn, AF_INET, SOCK_STREAM, tcp4_addr, (),
- psutil.CONN_LISTEN,
- ("all", "inet", "inet4", "tcp", "tcp4"))
- # UDP v4
- elif p.pid == udp4_proc.pid:
- check_conn(p, conn, AF_INET, SOCK_DGRAM, udp4_addr, (),
- psutil.CONN_NONE,
- ("all", "inet", "inet4", "udp", "udp4"))
- # TCP v6
- elif p.pid == getattr(tcp6_proc, "pid", None):
- check_conn(p, conn, AF_INET6, SOCK_STREAM, tcp6_addr, (),
- psutil.CONN_LISTEN,
- ("all", "inet", "inet6", "tcp", "tcp6"))
- # UDP v6
- elif p.pid == getattr(udp6_proc, "pid", None):
- check_conn(p, conn, AF_INET6, SOCK_DGRAM, udp6_addr, (),
- psutil.CONN_NONE,
- ("all", "inet", "inet6", "udp", "udp6"))
-
- # err
- self.assertRaises(ValueError, p.connections, kind='???')
-
- def test_multi_sockets_filtering(self):
- with create_sockets() as socks:
- cons = thisproc.connections(kind='all')
- self.assertEqual(len(cons), len(socks))
- # tcp
- cons = thisproc.connections(kind='tcp')
- self.assertEqual(len(cons), 2 if supports_ipv6() else 1)
- for conn in cons:
- self.assertIn(conn.family, (AF_INET, AF_INET6))
- self.assertEqual(conn.type, SOCK_STREAM)
- # tcp4
- cons = thisproc.connections(kind='tcp4')
- self.assertEqual(len(cons), 1)
- self.assertEqual(cons[0].family, AF_INET)
- self.assertEqual(cons[0].type, SOCK_STREAM)
- # tcp6
- if supports_ipv6():
- cons = thisproc.connections(kind='tcp6')
- self.assertEqual(len(cons), 1)
- self.assertEqual(cons[0].family, AF_INET6)
- self.assertEqual(cons[0].type, SOCK_STREAM)
- # udp
- cons = thisproc.connections(kind='udp')
- self.assertEqual(len(cons), 2 if supports_ipv6() else 1)
- for conn in cons:
- self.assertIn(conn.family, (AF_INET, AF_INET6))
- self.assertEqual(conn.type, SOCK_DGRAM)
- # udp4
- cons = thisproc.connections(kind='udp4')
- self.assertEqual(len(cons), 1)
- self.assertEqual(cons[0].family, AF_INET)
- self.assertEqual(cons[0].type, SOCK_DGRAM)
- # udp6
- if supports_ipv6():
- cons = thisproc.connections(kind='udp6')
- self.assertEqual(len(cons), 1)
- self.assertEqual(cons[0].family, AF_INET6)
- self.assertEqual(cons[0].type, SOCK_DGRAM)
- # inet
- cons = thisproc.connections(kind='inet')
- self.assertEqual(len(cons), 4 if supports_ipv6() else 2)
- for conn in cons:
- self.assertIn(conn.family, (AF_INET, AF_INET6))
- self.assertIn(conn.type, (SOCK_STREAM, SOCK_DGRAM))
- # inet6
- if supports_ipv6():
- cons = thisproc.connections(kind='inet6')
- self.assertEqual(len(cons), 2)
- for conn in cons:
- self.assertEqual(conn.family, AF_INET6)
- self.assertIn(conn.type, (SOCK_STREAM, SOCK_DGRAM))
- # unix
- if HAS_CONNECTIONS_UNIX:
- cons = thisproc.connections(kind='unix')
- self.assertEqual(len(cons), 3)
- for conn in cons:
- self.assertEqual(conn.family, AF_UNIX)
- self.assertIn(conn.type, (SOCK_STREAM, SOCK_DGRAM))
-
-
-# =====================================================================
-# --- Miscellaneous tests
-# =====================================================================
-
-
-class TestSystemWideConnections(Base, unittest.TestCase):
- """Tests for net_connections()."""
-
- @skip_on_access_denied()
- def test_it(self):
- def check(cons, families, types_):
- AF_UNIX = getattr(socket, 'AF_UNIX', object())
- for conn in cons:
- self.assertIn(conn.family, families, msg=conn)
- if conn.family != AF_UNIX:
- self.assertIn(conn.type, types_, msg=conn)
- check_connection_ntuple(conn)
-
- with create_sockets():
- from psutil._common import conn_tmap
- for kind, groups in conn_tmap.items():
- # XXX: SunOS does not retrieve UNIX sockets.
- if kind == 'unix' and not HAS_CONNECTIONS_UNIX:
- continue
- families, types_ = groups
- cons = psutil.net_connections(kind)
- self.assertEqual(len(cons), len(set(cons)))
- check(cons, families, types_)
-
- self.assertRaises(ValueError, psutil.net_connections, kind='???')
-
- @skip_on_access_denied()
- def test_multi_socks(self):
- with create_sockets() as socks:
- cons = [x for x in psutil.net_connections(kind='all')
- if x.pid == os.getpid()]
- self.assertEqual(len(cons), len(socks))
-
- @skip_on_access_denied()
- # See: https://travis-ci.org/giampaolo/psutil/jobs/237566297
- @unittest.skipIf(MACOS and TRAVIS, "unreliable on MACOS + TRAVIS")
- def test_multi_sockets_procs(self):
- # Creates multiple sub processes, each creating different
- # sockets. For each process check that proc.connections()
- # and net_connections() return the same results.
- # This is done mainly to check whether net_connections()'s
- # pid is properly set, see:
- # https://github.com/giampaolo/psutil/issues/1013
- with create_sockets() as socks:
- expected = len(socks)
- pids = []
- times = 10
- for i in range(times):
- fname = os.path.realpath(TESTFN) + str(i)
- src = textwrap.dedent("""\
- import time, os
- from psutil.tests import create_sockets
- with create_sockets():
- with open('%s', 'w') as f:
- f.write(str(os.getpid()))
- time.sleep(60)
- """ % fname)
- sproc = pyrun(src)
- pids.append(sproc.pid)
- self.addCleanup(safe_rmpath, fname)
-
- # sync
- for i in range(times):
- fname = TESTFN + str(i)
- wait_for_file(fname)
-
- syscons = [x for x in psutil.net_connections(kind='all') if x.pid
- in pids]
- for pid in pids:
- self.assertEqual(len([x for x in syscons if x.pid == pid]),
- expected)
- p = psutil.Process(pid)
- self.assertEqual(len(p.connections('all')), expected)
-
-
-# =====================================================================
-# --- Miscellaneous tests
-# =====================================================================
-
-
-class TestMisc(unittest.TestCase):
-
- def test_connection_constants(self):
- ints = []
- strs = []
- for name in dir(psutil):
- if name.startswith('CONN_'):
- num = getattr(psutil, name)
- str_ = str(num)
- assert str_.isupper(), str_
- self.assertNotIn(str, strs)
- self.assertNotIn(num, ints)
- ints.append(num)
- strs.append(str_)
- if SUNOS:
- psutil.CONN_IDLE
- psutil.CONN_BOUND
- if WINDOWS:
- psutil.CONN_DELETE_TCB
-
-
-if __name__ == '__main__':
- run_test_module_by_name(__file__)
diff --git a/server/www/packages/packages-darwin/x64/psutil/tests/test_contracts.py b/server/www/packages/packages-darwin/x64/psutil/tests/test_contracts.py
deleted file mode 100644
index 877a5c0..0000000
--- a/server/www/packages/packages-darwin/x64/psutil/tests/test_contracts.py
+++ /dev/null
@@ -1,642 +0,0 @@
-#!/usr/bin/env python
-
-# 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.
-
-"""Contracts tests. These tests mainly check API sanity in terms of
-returned types and APIs availability.
-Some of these are duplicates of tests test_system.py and test_process.py
-"""
-
-import errno
-import os
-import stat
-import time
-import traceback
-import warnings
-from contextlib import closing
-
-from psutil import AIX
-from psutil import BSD
-from psutil import FREEBSD
-from psutil import LINUX
-from psutil import MACOS
-from psutil import NETBSD
-from psutil import OPENBSD
-from psutil import POSIX
-from psutil import SUNOS
-from psutil import WINDOWS
-from psutil._compat import long
-from psutil.tests import bind_unix_socket
-from psutil.tests import check_connection_ntuple
-from psutil.tests import get_kernel_version
-from psutil.tests import HAS_CONNECTIONS_UNIX
-from psutil.tests import HAS_RLIMIT
-from psutil.tests import HAS_SENSORS_FANS
-from psutil.tests import HAS_SENSORS_TEMPERATURES
-from psutil.tests import is_namedtuple
-from psutil.tests import run_test_module_by_name
-from psutil.tests import safe_rmpath
-from psutil.tests import skip_on_access_denied
-from psutil.tests import TESTFN
-from psutil.tests import unittest
-from psutil.tests import unix_socket_path
-from psutil.tests import VALID_PROC_STATUSES
-from psutil.tests import warn
-import psutil
-
-
-# ===================================================================
-# --- APIs availability
-# ===================================================================
-
-
-class TestAvailability(unittest.TestCase):
- """Make sure code reflects what doc promises in terms of APIs
- availability.
- """
-
- def test_cpu_affinity(self):
- hasit = LINUX or WINDOWS or FREEBSD
- self.assertEqual(hasattr(psutil.Process, "cpu_affinity"), hasit)
-
- def test_win_service(self):
- self.assertEqual(hasattr(psutil, "win_service_iter"), WINDOWS)
- self.assertEqual(hasattr(psutil, "win_service_get"), WINDOWS)
-
- def test_PROCFS_PATH(self):
- self.assertEqual(hasattr(psutil, "PROCFS_PATH"),
- LINUX or SUNOS or AIX)
-
- def test_win_priority(self):
- ae = self.assertEqual
- ae(hasattr(psutil, "ABOVE_NORMAL_PRIORITY_CLASS"), WINDOWS)
- ae(hasattr(psutil, "BELOW_NORMAL_PRIORITY_CLASS"), WINDOWS)
- ae(hasattr(psutil, "HIGH_PRIORITY_CLASS"), WINDOWS)
- ae(hasattr(psutil, "IDLE_PRIORITY_CLASS"), WINDOWS)
- ae(hasattr(psutil, "NORMAL_PRIORITY_CLASS"), WINDOWS)
- ae(hasattr(psutil, "REALTIME_PRIORITY_CLASS"), WINDOWS)
-
- def test_linux_ioprio(self):
- ae = self.assertEqual
- ae(hasattr(psutil, "IOPRIO_CLASS_NONE"), LINUX)
- ae(hasattr(psutil, "IOPRIO_CLASS_RT"), LINUX)
- ae(hasattr(psutil, "IOPRIO_CLASS_BE"), LINUX)
- ae(hasattr(psutil, "IOPRIO_CLASS_IDLE"), LINUX)
-
- def test_linux_rlimit(self):
- ae = self.assertEqual
- hasit = LINUX and get_kernel_version() >= (2, 6, 36)
- ae(hasattr(psutil.Process, "rlimit"), hasit)
- ae(hasattr(psutil, "RLIM_INFINITY"), hasit)
- ae(hasattr(psutil, "RLIMIT_AS"), hasit)
- ae(hasattr(psutil, "RLIMIT_CORE"), hasit)
- ae(hasattr(psutil, "RLIMIT_CPU"), hasit)
- ae(hasattr(psutil, "RLIMIT_DATA"), hasit)
- ae(hasattr(psutil, "RLIMIT_FSIZE"), hasit)
- ae(hasattr(psutil, "RLIMIT_LOCKS"), hasit)
- ae(hasattr(psutil, "RLIMIT_MEMLOCK"), hasit)
- ae(hasattr(psutil, "RLIMIT_NOFILE"), hasit)
- ae(hasattr(psutil, "RLIMIT_NPROC"), hasit)
- ae(hasattr(psutil, "RLIMIT_RSS"), hasit)
- ae(hasattr(psutil, "RLIMIT_STACK"), hasit)
-
- hasit = LINUX and get_kernel_version() >= (3, 0)
- ae(hasattr(psutil, "RLIMIT_MSGQUEUE"), hasit)
- ae(hasattr(psutil, "RLIMIT_NICE"), hasit)
- ae(hasattr(psutil, "RLIMIT_RTPRIO"), hasit)
- ae(hasattr(psutil, "RLIMIT_RTTIME"), hasit)
- ae(hasattr(psutil, "RLIMIT_SIGPENDING"), hasit)
-
- def test_cpu_freq(self):
- linux = (LINUX and
- (os.path.exists("/sys/devices/system/cpu/cpufreq") or
- os.path.exists("/sys/devices/system/cpu/cpu0/cpufreq")))
- self.assertEqual(hasattr(psutil, "cpu_freq"),
- linux or MACOS or WINDOWS)
-
- def test_sensors_temperatures(self):
- self.assertEqual(
- hasattr(psutil, "sensors_temperatures"), LINUX)
-
- def test_sensors_fans(self):
- self.assertEqual(hasattr(psutil, "sensors_fans"), LINUX)
-
- def test_battery(self):
- self.assertEqual(hasattr(psutil, "sensors_battery"),
- LINUX or WINDOWS or FREEBSD or MACOS)
-
- def test_proc_environ(self):
- self.assertEqual(hasattr(psutil.Process, "environ"),
- LINUX or MACOS or WINDOWS)
-
- def test_proc_uids(self):
- self.assertEqual(hasattr(psutil.Process, "uids"), POSIX)
-
- def test_proc_gids(self):
- self.assertEqual(hasattr(psutil.Process, "uids"), POSIX)
-
- def test_proc_terminal(self):
- self.assertEqual(hasattr(psutil.Process, "terminal"), POSIX)
-
- def test_proc_ionice(self):
- self.assertEqual(hasattr(psutil.Process, "ionice"), LINUX or WINDOWS)
-
- def test_proc_rlimit(self):
- self.assertEqual(hasattr(psutil.Process, "rlimit"), LINUX)
-
- def test_proc_io_counters(self):
- hasit = hasattr(psutil.Process, "io_counters")
- self.assertEqual(hasit, False if MACOS or SUNOS else True)
-
- def test_proc_num_fds(self):
- self.assertEqual(hasattr(psutil.Process, "num_fds"), POSIX)
-
- def test_proc_num_handles(self):
- self.assertEqual(hasattr(psutil.Process, "num_handles"), WINDOWS)
-
- def test_proc_cpu_affinity(self):
- self.assertEqual(hasattr(psutil.Process, "cpu_affinity"),
- LINUX or WINDOWS or FREEBSD)
-
- def test_proc_cpu_num(self):
- self.assertEqual(hasattr(psutil.Process, "cpu_num"),
- LINUX or FREEBSD or SUNOS)
-
- def test_proc_memory_maps(self):
- hasit = hasattr(psutil.Process, "memory_maps")
- self.assertEqual(hasit, False if OPENBSD or NETBSD or AIX else True)
-
-
-# ===================================================================
-# --- Test deprecations
-# ===================================================================
-
-
-class TestDeprecations(unittest.TestCase):
-
- def test_memory_info_ex(self):
- with warnings.catch_warnings(record=True) as ws:
- psutil.Process().memory_info_ex()
- w = ws[0]
- self.assertIsInstance(w.category(), FutureWarning)
- self.assertIn("memory_info_ex() is deprecated", str(w.message))
- self.assertIn("use memory_info() instead", str(w.message))
-
-
-# ===================================================================
-# --- System API types
-# ===================================================================
-
-
-class TestSystem(unittest.TestCase):
- """Check the return types of system related APIs.
- Mainly we want to test we never return unicode on Python 2, see:
- https://github.com/giampaolo/psutil/issues/1039
- """
-
- @classmethod
- def setUpClass(cls):
- cls.proc = psutil.Process()
-
- def tearDown(self):
- safe_rmpath(TESTFN)
-
- def test_cpu_times(self):
- # Duplicate of test_system.py. Keep it anyway.
- ret = psutil.cpu_times()
- assert is_namedtuple(ret)
- for n in ret:
- self.assertIsInstance(n, float)
- self.assertGreaterEqual(n, 0)
-
- def test_io_counters(self):
- # Duplicate of test_system.py. Keep it anyway.
- for k in psutil.disk_io_counters(perdisk=True):
- self.assertIsInstance(k, str)
-
- def test_disk_partitions(self):
- # Duplicate of test_system.py. Keep it anyway.
- for disk in psutil.disk_partitions():
- self.assertIsInstance(disk.device, str)
- self.assertIsInstance(disk.mountpoint, str)
- self.assertIsInstance(disk.fstype, str)
- self.assertIsInstance(disk.opts, str)
-
- @unittest.skipIf(not POSIX, 'POSIX only')
- @unittest.skipIf(not HAS_CONNECTIONS_UNIX, "can't list UNIX sockets")
- @skip_on_access_denied(only_if=MACOS)
- def test_net_connections(self):
- with unix_socket_path() as name:
- with closing(bind_unix_socket(name)):
- cons = psutil.net_connections(kind='unix')
- assert cons
- for conn in cons:
- self.assertIsInstance(conn.laddr, str)
-
- def test_net_if_addrs(self):
- # Duplicate of test_system.py. Keep it anyway.
- for ifname, addrs in psutil.net_if_addrs().items():
- self.assertIsInstance(ifname, str)
- for addr in addrs:
- self.assertIsInstance(addr.address, str)
- self.assertIsInstance(addr.netmask, (str, type(None)))
- self.assertIsInstance(addr.broadcast, (str, type(None)))
-
- def test_net_if_stats(self):
- # Duplicate of test_system.py. Keep it anyway.
- for ifname, _ in psutil.net_if_stats().items():
- self.assertIsInstance(ifname, str)
-
- def test_net_io_counters(self):
- # Duplicate of test_system.py. Keep it anyway.
- for ifname, _ in psutil.net_io_counters(pernic=True).items():
- self.assertIsInstance(ifname, str)
-
- @unittest.skipIf(not HAS_SENSORS_FANS, "not supported")
- def test_sensors_fans(self):
- # Duplicate of test_system.py. Keep it anyway.
- for name, units in psutil.sensors_fans().items():
- self.assertIsInstance(name, str)
- for unit in units:
- self.assertIsInstance(unit.label, str)
-
- @unittest.skipIf(not HAS_SENSORS_TEMPERATURES, "not supported")
- def test_sensors_temperatures(self):
- # Duplicate of test_system.py. Keep it anyway.
- for name, units in psutil.sensors_temperatures().items():
- self.assertIsInstance(name, str)
- for unit in units:
- self.assertIsInstance(unit.label, str)
-
- def test_users(self):
- # Duplicate of test_system.py. Keep it anyway.
- for user in psutil.users():
- self.assertIsInstance(user.name, str)
- self.assertIsInstance(user.terminal, (str, type(None)))
- self.assertIsInstance(user.host, (str, type(None)))
- self.assertIsInstance(user.pid, (int, type(None)))
-
-
-# ===================================================================
-# --- Featch all processes test
-# ===================================================================
-
-
-class TestFetchAllProcesses(unittest.TestCase):
- """Test which iterates over all running processes and performs
- some sanity checks against Process API's returned values.
- """
-
- def test_fetch_all(self):
- valid_procs = 0
- excluded_names = set([
- 'send_signal', 'suspend', 'resume', 'terminate', 'kill', 'wait',
- 'as_dict', 'parent', 'children', 'memory_info_ex', 'oneshot',
- ])
- if LINUX and not HAS_RLIMIT:
- excluded_names.add('rlimit')
- attrs = []
- for name in dir(psutil.Process):
- if name.startswith("_"):
- continue
- if name in excluded_names:
- continue
- attrs.append(name)
-
- default = object()
- failures = []
- for p in psutil.process_iter():
- with p.oneshot():
- for name in attrs:
- ret = default
- try:
- args = ()
- kwargs = {}
- attr = getattr(p, name, None)
- if attr is not None and callable(attr):
- if name == 'rlimit':
- args = (psutil.RLIMIT_NOFILE,)
- elif name == 'memory_maps':
- kwargs = {'grouped': False}
- ret = attr(*args, **kwargs)
- else:
- ret = attr
- valid_procs += 1
- except NotImplementedError:
- msg = "%r was skipped because not implemented" % (
- self.__class__.__name__ + '.test_' + name)
- warn(msg)
- except (psutil.NoSuchProcess, psutil.AccessDenied) as err:
- self.assertEqual(err.pid, p.pid)
- if err.name:
- # make sure exception's name attr is set
- # with the actual process name
- self.assertEqual(err.name, p.name())
- assert str(err)
- assert err.msg
- except Exception as err:
- s = '\n' + '=' * 70 + '\n'
- s += "FAIL: test_%s (proc=%s" % (name, p)
- if ret != default:
- s += ", ret=%s)" % repr(ret)
- s += ')\n'
- s += '-' * 70
- s += "\n%s" % traceback.format_exc()
- s = "\n".join((" " * 4) + i for i in s.splitlines())
- s += '\n'
- failures.append(s)
- break
- else:
- if ret not in (0, 0.0, [], None, '', {}):
- assert ret, ret
- meth = getattr(self, name)
- meth(ret, p)
-
- if failures:
- self.fail(''.join(failures))
-
- # we should always have a non-empty list, not including PID 0 etc.
- # special cases.
- assert valid_procs
-
- def cmdline(self, ret, proc):
- self.assertIsInstance(ret, list)
- for part in ret:
- self.assertIsInstance(part, str)
-
- def exe(self, ret, proc):
- self.assertIsInstance(ret, (str, type(None)))
- if not ret:
- self.assertEqual(ret, '')
- else:
- assert os.path.isabs(ret), ret
- # Note: os.stat() may return False even if the file is there
- # hence we skip the test, see:
- # http://stackoverflow.com/questions/3112546/os-path-exists-lies
- if POSIX and os.path.isfile(ret):
- if hasattr(os, 'access') and hasattr(os, "X_OK"):
- # XXX may fail on MACOS
- assert os.access(ret, os.X_OK)
-
- def pid(self, ret, proc):
- self.assertIsInstance(ret, int)
- self.assertGreaterEqual(ret, 0)
-
- def ppid(self, ret, proc):
- self.assertIsInstance(ret, (int, long))
- self.assertGreaterEqual(ret, 0)
-
- def name(self, ret, proc):
- self.assertIsInstance(ret, str)
- # on AIX, "" processes don't have names
- if not AIX:
- assert ret
-
- def create_time(self, ret, proc):
- self.assertIsInstance(ret, float)
- try:
- self.assertGreaterEqual(ret, 0)
- except AssertionError:
- # XXX
- if OPENBSD and proc.status() == psutil.STATUS_ZOMBIE:
- pass
- else:
- raise
- # this can't be taken for granted on all platforms
- # self.assertGreaterEqual(ret, psutil.boot_time())
- # make sure returned value can be pretty printed
- # with strftime
- time.strftime("%Y %m %d %H:%M:%S", time.localtime(ret))
-
- def uids(self, ret, proc):
- assert is_namedtuple(ret)
- for uid in ret:
- self.assertIsInstance(uid, int)
- self.assertGreaterEqual(uid, 0)
-
- def gids(self, ret, proc):
- assert is_namedtuple(ret)
- # note: testing all gids as above seems not to be reliable for
- # gid == 30 (nodoby); not sure why.
- for gid in ret:
- self.assertIsInstance(gid, int)
- if not MACOS and not NETBSD:
- self.assertGreaterEqual(gid, 0)
-
- def username(self, ret, proc):
- self.assertIsInstance(ret, str)
- assert ret
-
- def status(self, ret, proc):
- self.assertIsInstance(ret, str)
- assert ret
- self.assertNotEqual(ret, '?') # XXX
- self.assertIn(ret, VALID_PROC_STATUSES)
-
- def io_counters(self, ret, proc):
- assert is_namedtuple(ret)
- for field in ret:
- self.assertIsInstance(field, (int, long))
- if field != -1:
- self.assertGreaterEqual(field, 0)
-
- def ionice(self, ret, proc):
- if POSIX:
- assert is_namedtuple(ret)
- for field in ret:
- self.assertIsInstance(field, int)
- if LINUX:
- self.assertGreaterEqual(ret.ioclass, 0)
- self.assertGreaterEqual(ret.value, 0)
- else:
- self.assertGreaterEqual(ret, 0)
- self.assertIn(ret, (0, 1, 2))
-
- def num_threads(self, ret, proc):
- self.assertIsInstance(ret, int)
- self.assertGreaterEqual(ret, 1)
-
- def threads(self, ret, proc):
- self.assertIsInstance(ret, list)
- for t in ret:
- assert is_namedtuple(t)
- self.assertGreaterEqual(t.id, 0)
- self.assertGreaterEqual(t.user_time, 0)
- self.assertGreaterEqual(t.system_time, 0)
- for field in t:
- self.assertIsInstance(field, (int, float))
-
- def cpu_times(self, ret, proc):
- assert is_namedtuple(ret)
- for n in ret:
- self.assertIsInstance(n, float)
- self.assertGreaterEqual(n, 0)
- # TODO: check ntuple fields
-
- def cpu_percent(self, ret, proc):
- self.assertIsInstance(ret, float)
- assert 0.0 <= ret <= 100.0, ret
-
- def cpu_num(self, ret, proc):
- self.assertIsInstance(ret, int)
- if FREEBSD and ret == -1:
- return
- self.assertGreaterEqual(ret, 0)
- if psutil.cpu_count() == 1:
- self.assertEqual(ret, 0)
- self.assertIn(ret, list(range(psutil.cpu_count())))
-
- def memory_info(self, ret, proc):
- assert is_namedtuple(ret)
- for value in ret:
- self.assertIsInstance(value, (int, long))
- self.assertGreaterEqual(value, 0)
- if POSIX and not AIX and ret.vms != 0:
- # VMS is always supposed to be the highest
- for name in ret._fields:
- if name != 'vms':
- value = getattr(ret, name)
- self.assertGreater(ret.vms, value, msg=ret)
- elif WINDOWS:
- self.assertGreaterEqual(ret.peak_wset, ret.wset)
- self.assertGreaterEqual(ret.peak_paged_pool, ret.paged_pool)
- self.assertGreaterEqual(ret.peak_nonpaged_pool, ret.nonpaged_pool)
- self.assertGreaterEqual(ret.peak_pagefile, ret.pagefile)
-
- def memory_full_info(self, ret, proc):
- assert is_namedtuple(ret)
- total = psutil.virtual_memory().total
- for name in ret._fields:
- value = getattr(ret, name)
- self.assertIsInstance(value, (int, long))
- self.assertGreaterEqual(value, 0, msg=(name, value))
- if LINUX and name in ('vms', 'data'):
- # On Linux there are processes (e.g. 'goa-daemon') whose
- # VMS is incredibly high for some reason.
- continue
- self.assertLessEqual(value, total, msg=(name, value, total))
-
- if LINUX:
- self.assertGreaterEqual(ret.pss, ret.uss)
-
- def open_files(self, ret, proc):
- self.assertIsInstance(ret, list)
- for f in ret:
- self.assertIsInstance(f.fd, int)
- self.assertIsInstance(f.path, str)
- if WINDOWS:
- self.assertEqual(f.fd, -1)
- elif LINUX:
- self.assertIsInstance(f.position, int)
- self.assertIsInstance(f.mode, str)
- self.assertIsInstance(f.flags, int)
- self.assertGreaterEqual(f.position, 0)
- self.assertIn(f.mode, ('r', 'w', 'a', 'r+', 'a+'))
- self.assertGreater(f.flags, 0)
- elif BSD and not f.path:
- # XXX see: https://github.com/giampaolo/psutil/issues/595
- continue
- assert os.path.isabs(f.path), f
- assert os.path.isfile(f.path), f
-
- def num_fds(self, ret, proc):
- self.assertIsInstance(ret, int)
- self.assertGreaterEqual(ret, 0)
-
- def connections(self, ret, proc):
- self.assertEqual(len(ret), len(set(ret)))
- for conn in ret:
- check_connection_ntuple(conn)
-
- def cwd(self, ret, proc):
- if ret: # 'ret' can be None or empty
- self.assertIsInstance(ret, str)
- assert os.path.isabs(ret), ret
- try:
- st = os.stat(ret)
- except OSError as err:
- if WINDOWS and err.errno in \
- psutil._psplatform.ACCESS_DENIED_SET:
- pass
- # directory has been removed in mean time
- elif err.errno != errno.ENOENT:
- raise
- else:
- assert stat.S_ISDIR(st.st_mode)
-
- def memory_percent(self, ret, proc):
- self.assertIsInstance(ret, float)
- assert 0 <= ret <= 100, ret
-
- def is_running(self, ret, proc):
- self.assertIsInstance(ret, bool)
-
- def cpu_affinity(self, ret, proc):
- self.assertIsInstance(ret, list)
- assert ret != [], ret
- cpus = range(psutil.cpu_count())
- for n in ret:
- self.assertIsInstance(n, int)
- self.assertIn(n, cpus)
-
- def terminal(self, ret, proc):
- self.assertIsInstance(ret, (str, type(None)))
- if ret is not None:
- assert os.path.isabs(ret), ret
- assert os.path.exists(ret), ret
-
- def memory_maps(self, ret, proc):
- for nt in ret:
- self.assertIsInstance(nt.addr, str)
- self.assertIsInstance(nt.perms, str)
- self.assertIsInstance(nt.path, str)
- for fname in nt._fields:
- value = getattr(nt, fname)
- if fname == 'path':
- if not value.startswith('['):
- assert os.path.isabs(nt.path), nt.path
- # commented as on Linux we might get
- # '/foo/bar (deleted)'
- # assert os.path.exists(nt.path), nt.path
- elif fname in ('addr', 'perms'):
- assert value
- else:
- self.assertIsInstance(value, (int, long))
- self.assertGreaterEqual(value, 0)
-
- def num_handles(self, ret, proc):
- self.assertIsInstance(ret, int)
- self.assertGreaterEqual(ret, 0)
-
- def nice(self, ret, proc):
- self.assertIsInstance(ret, int)
- if POSIX:
- assert -20 <= ret <= 20, ret
- else:
- priorities = [getattr(psutil, x) for x in dir(psutil)
- if x.endswith('_PRIORITY_CLASS')]
- self.assertIn(ret, priorities)
-
- def num_ctx_switches(self, ret, proc):
- assert is_namedtuple(ret)
- for value in ret:
- self.assertIsInstance(value, (int, long))
- self.assertGreaterEqual(value, 0)
-
- def rlimit(self, ret, proc):
- self.assertIsInstance(ret, tuple)
- self.assertEqual(len(ret), 2)
- self.assertGreaterEqual(ret[0], -1)
- self.assertGreaterEqual(ret[1], -1)
-
- def environ(self, ret, proc):
- self.assertIsInstance(ret, dict)
- for k, v in ret.items():
- self.assertIsInstance(k, str)
- self.assertIsInstance(v, str)
-
-
-if __name__ == '__main__':
- run_test_module_by_name(__file__)
diff --git a/server/www/packages/packages-darwin/x64/psutil/tests/test_linux.py b/server/www/packages/packages-darwin/x64/psutil/tests/test_linux.py
deleted file mode 100644
index 4e652a9..0000000
--- a/server/www/packages/packages-darwin/x64/psutil/tests/test_linux.py
+++ /dev/null
@@ -1,2005 +0,0 @@
-#!/usr/bin/env python
-
-# 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.
-
-"""Linux specific tests."""
-
-from __future__ import division
-import collections
-import contextlib
-import errno
-import glob
-import io
-import os
-import re
-import shutil
-import socket
-import struct
-import tempfile
-import textwrap
-import time
-import warnings
-
-import psutil
-from psutil import LINUX
-from psutil._compat import basestring
-from psutil._compat import PY3
-from psutil._compat import u
-from psutil.tests import call_until
-from psutil.tests import HAS_BATTERY
-from psutil.tests import HAS_CPU_FREQ
-from psutil.tests import HAS_RLIMIT
-from psutil.tests import MEMORY_TOLERANCE
-from psutil.tests import mock
-from psutil.tests import PYPY
-from psutil.tests import pyrun
-from psutil.tests import reap_children
-from psutil.tests import reload_module
-from psutil.tests import retry_before_failing
-from psutil.tests import run_test_module_by_name
-from psutil.tests import safe_rmpath
-from psutil.tests import sh
-from psutil.tests import skip_on_not_implemented
-from psutil.tests import TESTFN
-from psutil.tests import ThreadTask
-from psutil.tests import TRAVIS
-from psutil.tests import unittest
-from psutil.tests import which
-
-
-HERE = os.path.abspath(os.path.dirname(__file__))
-SIOCGIFADDR = 0x8915
-SIOCGIFCONF = 0x8912
-SIOCGIFHWADDR = 0x8927
-if LINUX:
- SECTOR_SIZE = 512
-
-
-# =====================================================================
-# --- utils
-# =====================================================================
-
-
-def get_ipv4_address(ifname):
- import fcntl
- ifname = ifname[:15]
- if PY3:
- ifname = bytes(ifname, 'ascii')
- s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
- with contextlib.closing(s):
- return socket.inet_ntoa(
- fcntl.ioctl(s.fileno(),
- SIOCGIFADDR,
- struct.pack('256s', ifname))[20:24])
-
-
-def get_mac_address(ifname):
- import fcntl
- ifname = ifname[:15]
- if PY3:
- ifname = bytes(ifname, 'ascii')
- s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
- with contextlib.closing(s):
- info = fcntl.ioctl(
- s.fileno(), SIOCGIFHWADDR, struct.pack('256s', ifname))
- if PY3:
- def ord(x):
- return x
- else:
- import __builtin__
- ord = __builtin__.ord
- return ''.join(['%02x:' % ord(char) for char in info[18:24]])[:-1]
-
-
-def free_swap():
- """Parse 'free' cmd and return swap memory's s total, used and free
- values.
- """
- out = sh('free -b')
- lines = out.split('\n')
- for line in lines:
- if line.startswith('Swap'):
- _, total, used, free = line.split()
- nt = collections.namedtuple('free', 'total used free')
- return nt(int(total), int(used), int(free))
- raise ValueError(
- "can't find 'Swap' in 'free' output:\n%s" % '\n'.join(lines))
-
-
-def free_physmem():
- """Parse 'free' cmd and return physical memory's total, used
- and free values.
- """
- # Note: free can have 2 different formats, invalidating 'shared'
- # and 'cached' memory which may have different positions so we
- # do not return them.
- # https://github.com/giampaolo/psutil/issues/538#issuecomment-57059946
- out = sh('free -b')
- lines = out.split('\n')
- for line in lines:
- if line.startswith('Mem'):
- total, used, free, shared = \
- [int(x) for x in line.split()[1:5]]
- nt = collections.namedtuple(
- 'free', 'total used free shared output')
- return nt(total, used, free, shared, out)
- raise ValueError(
- "can't find 'Mem' in 'free' output:\n%s" % '\n'.join(lines))
-
-
-def vmstat(stat):
- out = sh("vmstat -s")
- for line in out.split("\n"):
- line = line.strip()
- if stat in line:
- return int(line.split(' ')[0])
- raise ValueError("can't find %r in 'vmstat' output" % stat)
-
-
-def get_free_version_info():
- out = sh("free -V").strip()
- return tuple(map(int, out.split()[-1].split('.')))
-
-
-@contextlib.contextmanager
-def mock_open_content(for_path, content):
- """Mock open() builtin and forces it to return a certain `content`
- on read() if the path being opened matches `for_path`.
- """
- def open_mock(name, *args, **kwargs):
- if name == for_path:
- if PY3:
- if isinstance(content, basestring):
- return io.StringIO(content)
- else:
- return io.BytesIO(content)
- else:
- return io.BytesIO(content)
- else:
- return orig_open(name, *args, **kwargs)
-
- orig_open = open
- patch_point = 'builtins.open' if PY3 else '__builtin__.open'
- with mock.patch(patch_point, create=True, side_effect=open_mock) as m:
- yield m
-
-
-@contextlib.contextmanager
-def mock_open_exception(for_path, exc):
- """Mock open() builtin and raises `exc` if the path being opened
- matches `for_path`.
- """
- def open_mock(name, *args, **kwargs):
- if name == for_path:
- raise exc
- else:
- return orig_open(name, *args, **kwargs)
-
- orig_open = open
- patch_point = 'builtins.open' if PY3 else '__builtin__.open'
- with mock.patch(patch_point, create=True, side_effect=open_mock) as m:
- yield m
-
-
-# =====================================================================
-# --- system virtual memory
-# =====================================================================
-
-
-@unittest.skipIf(not LINUX, "LINUX only")
-class TestSystemVirtualMemory(unittest.TestCase):
-
- def test_total(self):
- # free_value = free_physmem().total
- # psutil_value = psutil.virtual_memory().total
- # self.assertEqual(free_value, psutil_value)
- vmstat_value = vmstat('total memory') * 1024
- psutil_value = psutil.virtual_memory().total
- self.assertAlmostEqual(vmstat_value, psutil_value)
-
- # Older versions of procps used slab memory to calculate used memory.
- # This got changed in:
- # https://gitlab.com/procps-ng/procps/commit/
- # 05d751c4f076a2f0118b914c5e51cfbb4762ad8e
- @unittest.skipIf(LINUX and get_free_version_info() < (3, 3, 12),
- "old free version")
- @retry_before_failing()
- def test_used(self):
- free = free_physmem()
- free_value = free.used
- psutil_value = psutil.virtual_memory().used
- self.assertAlmostEqual(
- free_value, psutil_value, delta=MEMORY_TOLERANCE,
- msg='%s %s \n%s' % (free_value, psutil_value, free.output))
-
- @unittest.skipIf(TRAVIS, "unreliable on TRAVIS")
- @retry_before_failing()
- def test_free(self):
- # _, _, free_value, _ = free_physmem()
- # psutil_value = psutil.virtual_memory().free
- # self.assertAlmostEqual(
- # free_value, psutil_value, delta=MEMORY_TOLERANCE)
- vmstat_value = vmstat('free memory') * 1024
- psutil_value = psutil.virtual_memory().free
- self.assertAlmostEqual(
- vmstat_value, psutil_value, delta=MEMORY_TOLERANCE)
-
- @retry_before_failing()
- def test_buffers(self):
- vmstat_value = vmstat('buffer memory') * 1024
- psutil_value = psutil.virtual_memory().buffers
- self.assertAlmostEqual(
- vmstat_value, psutil_value, delta=MEMORY_TOLERANCE)
-
- # https://travis-ci.org/giampaolo/psutil/jobs/226719664
- @unittest.skipIf(TRAVIS, "unreliable on TRAVIS")
- @retry_before_failing()
- def test_active(self):
- vmstat_value = vmstat('active memory') * 1024
- psutil_value = psutil.virtual_memory().active
- self.assertAlmostEqual(
- vmstat_value, psutil_value, delta=MEMORY_TOLERANCE)
-
- # https://travis-ci.org/giampaolo/psutil/jobs/227242952
- @unittest.skipIf(TRAVIS, "unreliable on TRAVIS")
- @retry_before_failing()
- def test_inactive(self):
- vmstat_value = vmstat('inactive memory') * 1024
- psutil_value = psutil.virtual_memory().inactive
- self.assertAlmostEqual(
- vmstat_value, psutil_value, delta=MEMORY_TOLERANCE)
-
- @retry_before_failing()
- def test_shared(self):
- free = free_physmem()
- free_value = free.shared
- if free_value == 0:
- raise unittest.SkipTest("free does not support 'shared' column")
- psutil_value = psutil.virtual_memory().shared
- self.assertAlmostEqual(
- free_value, psutil_value, delta=MEMORY_TOLERANCE,
- msg='%s %s \n%s' % (free_value, psutil_value, free.output))
-
- @retry_before_failing()
- def test_available(self):
- # "free" output format has changed at some point:
- # https://github.com/giampaolo/psutil/issues/538#issuecomment-147192098
- out = sh("free -b")
- lines = out.split('\n')
- if 'available' not in lines[0]:
- raise unittest.SkipTest("free does not support 'available' column")
- else:
- free_value = int(lines[1].split()[-1])
- psutil_value = psutil.virtual_memory().available
- self.assertAlmostEqual(
- free_value, psutil_value, delta=MEMORY_TOLERANCE,
- msg='%s %s \n%s' % (free_value, psutil_value, out))
-
- def test_warnings_on_misses(self):
- # Emulate a case where /proc/meminfo provides few info.
- # psutil is supposed to set the missing fields to 0 and
- # raise a warning.
- with mock_open_content(
- '/proc/meminfo',
- textwrap.dedent("""\
- Active(anon): 6145416 kB
- Active(file): 2950064 kB
- Inactive(anon): 574764 kB
- Inactive(file): 1567648 kB
- MemAvailable: -1 kB
- MemFree: 2057400 kB
- MemTotal: 16325648 kB
- SReclaimable: 346648 kB
- """).encode()) as m:
- with warnings.catch_warnings(record=True) as ws:
- warnings.simplefilter("always")
- ret = psutil.virtual_memory()
- assert m.called
- self.assertEqual(len(ws), 1)
- w = ws[0]
- assert w.filename.endswith('psutil/_pslinux.py')
- self.assertIn(
- "memory stats couldn't be determined", str(w.message))
- self.assertIn("cached", str(w.message))
- self.assertIn("shared", str(w.message))
- self.assertIn("active", str(w.message))
- self.assertIn("inactive", str(w.message))
- self.assertIn("buffers", str(w.message))
- self.assertIn("available", str(w.message))
- self.assertEqual(ret.cached, 0)
- self.assertEqual(ret.active, 0)
- self.assertEqual(ret.inactive, 0)
- self.assertEqual(ret.shared, 0)
- self.assertEqual(ret.buffers, 0)
- self.assertEqual(ret.available, 0)
- self.assertEqual(ret.slab, 0)
-
- def test_avail_old_percent(self):
- # Make sure that our calculation of avail mem for old kernels
- # is off by max 10%.
- from psutil._pslinux import calculate_avail_vmem
- from psutil._pslinux import open_binary
-
- mems = {}
- with open_binary('/proc/meminfo') as f:
- for line in f:
- fields = line.split()
- mems[fields[0]] = int(fields[1]) * 1024
-
- a = calculate_avail_vmem(mems)
- if b'MemAvailable:' in mems:
- b = mems[b'MemAvailable:']
- diff_percent = abs(a - b) / a * 100
- self.assertLess(diff_percent, 10)
-
- def test_avail_old_comes_from_kernel(self):
- # Make sure "MemAvailable:" coluimn is used instead of relying
- # on our internal algorithm to calculate avail mem.
- with mock_open_content(
- '/proc/meminfo',
- textwrap.dedent("""\
- Active: 9444728 kB
- Active(anon): 6145416 kB
- Active(file): 2950064 kB
- Buffers: 287952 kB
- Cached: 4818144 kB
- Inactive(file): 1578132 kB
- Inactive(anon): 574764 kB
- Inactive(file): 1567648 kB
- MemAvailable: 6574984 kB
- MemFree: 2057400 kB
- MemTotal: 16325648 kB
- Shmem: 577588 kB
- SReclaimable: 346648 kB
- """).encode()) as m:
- with warnings.catch_warnings(record=True) as ws:
- ret = psutil.virtual_memory()
- assert m.called
- self.assertEqual(ret.available, 6574984 * 1024)
- w = ws[0]
- self.assertIn(
- "inactive memory stats couldn't be determined", str(w.message))
-
- def test_avail_old_missing_fields(self):
- # Remove Active(file), Inactive(file) and SReclaimable
- # from /proc/meminfo and make sure the fallback is used
- # (free + cached),
- with mock_open_content(
- "/proc/meminfo",
- textwrap.dedent("""\
- Active: 9444728 kB
- Active(anon): 6145416 kB
- Buffers: 287952 kB
- Cached: 4818144 kB
- Inactive(file): 1578132 kB
- Inactive(anon): 574764 kB
- MemFree: 2057400 kB
- MemTotal: 16325648 kB
- Shmem: 577588 kB
- """).encode()) as m:
- with warnings.catch_warnings(record=True) as ws:
- ret = psutil.virtual_memory()
- assert m.called
- self.assertEqual(ret.available, 2057400 * 1024 + 4818144 * 1024)
- w = ws[0]
- self.assertIn(
- "inactive memory stats couldn't be determined", str(w.message))
-
- def test_avail_old_missing_zoneinfo(self):
- # Remove /proc/zoneinfo file. Make sure fallback is used
- # (free + cached).
- with mock_open_content(
- "/proc/meminfo",
- textwrap.dedent("""\
- Active: 9444728 kB
- Active(anon): 6145416 kB
- Active(file): 2950064 kB
- Buffers: 287952 kB
- Cached: 4818144 kB
- Inactive(file): 1578132 kB
- Inactive(anon): 574764 kB
- Inactive(file): 1567648 kB
- MemFree: 2057400 kB
- MemTotal: 16325648 kB
- Shmem: 577588 kB
- SReclaimable: 346648 kB
- """).encode()):
- with mock_open_exception(
- "/proc/zoneinfo",
- IOError(errno.ENOENT, 'no such file or directory')):
- with warnings.catch_warnings(record=True) as ws:
- ret = psutil.virtual_memory()
- self.assertEqual(
- ret.available, 2057400 * 1024 + 4818144 * 1024)
- w = ws[0]
- self.assertIn(
- "inactive memory stats couldn't be determined",
- str(w.message))
-
- def test_virtual_memory_mocked(self):
- # Emulate /proc/meminfo because neither vmstat nor free return slab.
- def open_mock(name, *args, **kwargs):
- if name == '/proc/meminfo':
- return io.BytesIO(textwrap.dedent("""\
- MemTotal: 100 kB
- MemFree: 2 kB
- MemAvailable: 3 kB
- Buffers: 4 kB
- Cached: 5 kB
- SwapCached: 6 kB
- Active: 7 kB
- Inactive: 8 kB
- Active(anon): 9 kB
- Inactive(anon): 10 kB
- Active(file): 11 kB
- Inactive(file): 12 kB
- Unevictable: 13 kB
- Mlocked: 14 kB
- SwapTotal: 15 kB
- SwapFree: 16 kB
- Dirty: 17 kB
- Writeback: 18 kB
- AnonPages: 19 kB
- Mapped: 20 kB
- Shmem: 21 kB
- Slab: 22 kB
- SReclaimable: 23 kB
- SUnreclaim: 24 kB
- KernelStack: 25 kB
- PageTables: 26 kB
- NFS_Unstable: 27 kB
- Bounce: 28 kB
- WritebackTmp: 29 kB
- CommitLimit: 30 kB
- Committed_AS: 31 kB
- VmallocTotal: 32 kB
- VmallocUsed: 33 kB
- VmallocChunk: 34 kB
- HardwareCorrupted: 35 kB
- AnonHugePages: 36 kB
- ShmemHugePages: 37 kB
- ShmemPmdMapped: 38 kB
- CmaTotal: 39 kB
- CmaFree: 40 kB
- HugePages_Total: 41 kB
- HugePages_Free: 42 kB
- HugePages_Rsvd: 43 kB
- HugePages_Surp: 44 kB
- Hugepagesize: 45 kB
- DirectMap46k: 46 kB
- DirectMap47M: 47 kB
- DirectMap48G: 48 kB
- """).encode())
- else:
- return orig_open(name, *args, **kwargs)
-
- orig_open = open
- patch_point = 'builtins.open' if PY3 else '__builtin__.open'
- with mock.patch(patch_point, create=True, side_effect=open_mock) as m:
- mem = psutil.virtual_memory()
- assert m.called
- self.assertEqual(mem.total, 100 * 1024)
- self.assertEqual(mem.free, 2 * 1024)
- self.assertEqual(mem.buffers, 4 * 1024)
- # cached mem also includes reclaimable memory
- self.assertEqual(mem.cached, (5 + 23) * 1024)
- self.assertEqual(mem.shared, 21 * 1024)
- self.assertEqual(mem.active, 7 * 1024)
- self.assertEqual(mem.inactive, 8 * 1024)
- self.assertEqual(mem.slab, 22 * 1024)
- self.assertEqual(mem.available, 3 * 1024)
-
-
-# =====================================================================
-# --- system swap memory
-# =====================================================================
-
-
-@unittest.skipIf(not LINUX, "LINUX only")
-class TestSystemSwapMemory(unittest.TestCase):
-
- @staticmethod
- def meminfo_has_swap_info():
- """Return True if /proc/meminfo provides swap metrics."""
- with open("/proc/meminfo") as f:
- data = f.read()
- return 'SwapTotal:' in data and 'SwapFree:' in data
-
- def test_total(self):
- free_value = free_swap().total
- psutil_value = psutil.swap_memory().total
- return self.assertAlmostEqual(
- free_value, psutil_value, delta=MEMORY_TOLERANCE)
-
- @retry_before_failing()
- def test_used(self):
- free_value = free_swap().used
- psutil_value = psutil.swap_memory().used
- return self.assertAlmostEqual(
- free_value, psutil_value, delta=MEMORY_TOLERANCE)
-
- @retry_before_failing()
- def test_free(self):
- free_value = free_swap().free
- psutil_value = psutil.swap_memory().free
- return self.assertAlmostEqual(
- free_value, psutil_value, delta=MEMORY_TOLERANCE)
-
- def test_missing_sin_sout(self):
- with mock.patch('psutil._pslinux.open', create=True) as m:
- with warnings.catch_warnings(record=True) as ws:
- warnings.simplefilter("always")
- ret = psutil.swap_memory()
- assert m.called
- self.assertEqual(len(ws), 1)
- w = ws[0]
- assert w.filename.endswith('psutil/_pslinux.py')
- self.assertIn(
- "'sin' and 'sout' swap memory stats couldn't "
- "be determined", str(w.message))
- self.assertEqual(ret.sin, 0)
- self.assertEqual(ret.sout, 0)
-
- def test_no_vmstat_mocked(self):
- # see https://github.com/giampaolo/psutil/issues/722
- with mock_open_exception(
- "/proc/vmstat",
- IOError(errno.ENOENT, 'no such file or directory')) as m:
- with warnings.catch_warnings(record=True) as ws:
- warnings.simplefilter("always")
- ret = psutil.swap_memory()
- assert m.called
- self.assertEqual(len(ws), 1)
- w = ws[0]
- assert w.filename.endswith('psutil/_pslinux.py')
- self.assertIn(
- "'sin' and 'sout' swap memory stats couldn't "
- "be determined and were set to 0",
- str(w.message))
- self.assertEqual(ret.sin, 0)
- self.assertEqual(ret.sout, 0)
-
- def test_meminfo_against_sysinfo(self):
- # Make sure the content of /proc/meminfo about swap memory
- # matches sysinfo() syscall, see:
- # https://github.com/giampaolo/psutil/issues/1015
- if not self.meminfo_has_swap_info():
- return unittest.skip("/proc/meminfo has no swap metrics")
- with mock.patch('psutil._pslinux.cext.linux_sysinfo') as m:
- swap = psutil.swap_memory()
- assert not m.called
- import psutil._psutil_linux as cext
- _, _, _, _, total, free, unit_multiplier = cext.linux_sysinfo()
- total *= unit_multiplier
- free *= unit_multiplier
- self.assertEqual(swap.total, total)
- self.assertEqual(swap.free, free)
-
- def test_emulate_meminfo_has_no_metrics(self):
- # Emulate a case where /proc/meminfo provides no swap metrics
- # in which case sysinfo() syscall is supposed to be used
- # as a fallback.
- with mock_open_content("/proc/meminfo", b"") as m:
- psutil.swap_memory()
- assert m.called
-
-
-# =====================================================================
-# --- system CPU
-# =====================================================================
-
-
-@unittest.skipIf(not LINUX, "LINUX only")
-class TestSystemCPU(unittest.TestCase):
-
- @unittest.skipIf(TRAVIS, "unknown failure on travis")
- def test_cpu_times(self):
- fields = psutil.cpu_times()._fields
- kernel_ver = re.findall(r'\d+\.\d+\.\d+', os.uname()[2])[0]
- kernel_ver_info = tuple(map(int, kernel_ver.split('.')))
- if kernel_ver_info >= (2, 6, 11):
- self.assertIn('steal', fields)
- else:
- self.assertNotIn('steal', fields)
- if kernel_ver_info >= (2, 6, 24):
- self.assertIn('guest', fields)
- else:
- self.assertNotIn('guest', fields)
- if kernel_ver_info >= (3, 2, 0):
- self.assertIn('guest_nice', fields)
- else:
- self.assertNotIn('guest_nice', fields)
-
- @unittest.skipIf(not os.path.exists("/sys/devices/system/cpu/online"),
- "/sys/devices/system/cpu/online does not exist")
- def test_cpu_count_logical_w_sysdev_cpu_online(self):
- with open("/sys/devices/system/cpu/online") as f:
- value = f.read().strip()
- if "-" in str(value):
- value = int(value.split('-')[1]) + 1
- self.assertEqual(psutil.cpu_count(), value)
-
- @unittest.skipIf(not os.path.exists("/sys/devices/system/cpu"),
- "/sys/devices/system/cpu does not exist")
- def test_cpu_count_logical_w_sysdev_cpu_num(self):
- ls = os.listdir("/sys/devices/system/cpu")
- count = len([x for x in ls if re.search(r"cpu\d+$", x) is not None])
- self.assertEqual(psutil.cpu_count(), count)
-
- @unittest.skipIf(not which("nproc"), "nproc utility not available")
- def test_cpu_count_logical_w_nproc(self):
- num = int(sh("nproc --all"))
- self.assertEqual(psutil.cpu_count(logical=True), num)
-
- @unittest.skipIf(not which("lscpu"), "lscpu utility not available")
- def test_cpu_count_logical_w_lscpu(self):
- out = sh("lscpu -p")
- num = len([x for x in out.split('\n') if not x.startswith('#')])
- self.assertEqual(psutil.cpu_count(logical=True), num)
-
- def test_cpu_count_logical_mocked(self):
- import psutil._pslinux
- original = psutil._pslinux.cpu_count_logical()
- # Here we want to mock os.sysconf("SC_NPROCESSORS_ONLN") in
- # order to cause the parsing of /proc/cpuinfo and /proc/stat.
- with mock.patch(
- 'psutil._pslinux.os.sysconf', side_effect=ValueError) as m:
- self.assertEqual(psutil._pslinux.cpu_count_logical(), original)
- assert m.called
-
- # Let's have open() return emtpy data and make sure None is
- # returned ('cause we mimick os.cpu_count()).
- with mock.patch('psutil._pslinux.open', create=True) as m:
- self.assertIsNone(psutil._pslinux.cpu_count_logical())
- self.assertEqual(m.call_count, 2)
- # /proc/stat should be the last one
- self.assertEqual(m.call_args[0][0], '/proc/stat')
-
- # Let's push this a bit further and make sure /proc/cpuinfo
- # parsing works as expected.
- with open('/proc/cpuinfo', 'rb') as f:
- cpuinfo_data = f.read()
- fake_file = io.BytesIO(cpuinfo_data)
- with mock.patch('psutil._pslinux.open',
- return_value=fake_file, create=True) as m:
- self.assertEqual(psutil._pslinux.cpu_count_logical(), original)
-
- # Finally, let's make /proc/cpuinfo return meaningless data;
- # this way we'll fall back on relying on /proc/stat
- with mock_open_content('/proc/cpuinfo', b"") as m:
- self.assertEqual(psutil._pslinux.cpu_count_logical(), original)
- m.called
-
- def test_cpu_count_physical_mocked(self):
- # Have open() return emtpy data and make sure None is returned
- # ('cause we want to mimick os.cpu_count())
- with mock.patch('psutil._pslinux.open', create=True) as m:
- self.assertIsNone(psutil._pslinux.cpu_count_physical())
- assert m.called
-
- @unittest.skipIf(not HAS_CPU_FREQ, "not supported")
- def test_cpu_freq_no_result(self):
- with mock.patch("psutil._pslinux.glob.glob", return_value=[]):
- self.assertIsNone(psutil.cpu_freq())
-
- @unittest.skipIf(TRAVIS, "fails on Travis")
- @unittest.skipIf(not HAS_CPU_FREQ, "not supported")
- def test_cpu_freq_use_second_file(self):
- # https://github.com/giampaolo/psutil/issues/981
- def glob_mock(pattern):
- if pattern.startswith("/sys/devices/system/cpu/cpufreq/policy"):
- flags.append(None)
- return []
- else:
- flags.append(None)
- return orig_glob(pattern)
-
- flags = []
- orig_glob = glob.glob
- with mock.patch("psutil._pslinux.glob.glob", side_effect=glob_mock,
- create=True):
- assert psutil.cpu_freq()
- self.assertEqual(len(flags), 2)
-
- @unittest.skipIf(not HAS_CPU_FREQ, "not supported")
- def test_cpu_freq_emulate_data(self):
- def open_mock(name, *args, **kwargs):
- if name.endswith('/scaling_cur_freq'):
- return io.BytesIO(b"500000")
- elif name.endswith('/scaling_min_freq'):
- return io.BytesIO(b"600000")
- elif name.endswith('/scaling_max_freq'):
- return io.BytesIO(b"700000")
- else:
- return orig_open(name, *args, **kwargs)
-
- orig_open = open
- patch_point = 'builtins.open' if PY3 else '__builtin__.open'
- with mock.patch(patch_point, side_effect=open_mock):
- with mock.patch(
- 'glob.glob',
- return_value=['/sys/devices/system/cpu/cpufreq/policy0']):
- freq = psutil.cpu_freq()
- self.assertEqual(freq.current, 500.0)
- self.assertEqual(freq.min, 600.0)
- self.assertEqual(freq.max, 700.0)
-
- @unittest.skipIf(not HAS_CPU_FREQ, "not supported")
- def test_cpu_freq_emulate_multi_cpu(self):
- def open_mock(name, *args, **kwargs):
- if name.endswith('/scaling_cur_freq'):
- return io.BytesIO(b"100000")
- elif name.endswith('/scaling_min_freq'):
- return io.BytesIO(b"200000")
- elif name.endswith('/scaling_max_freq'):
- return io.BytesIO(b"300000")
- else:
- return orig_open(name, *args, **kwargs)
-
- orig_open = open
- patch_point = 'builtins.open' if PY3 else '__builtin__.open'
- policies = ['/sys/devices/system/cpu/cpufreq/policy0',
- '/sys/devices/system/cpu/cpufreq/policy1',
- '/sys/devices/system/cpu/cpufreq/policy2']
- with mock.patch(patch_point, side_effect=open_mock):
- with mock.patch('glob.glob', return_value=policies):
- freq = psutil.cpu_freq()
- self.assertEqual(freq.current, 100.0)
- self.assertEqual(freq.min, 200.0)
- self.assertEqual(freq.max, 300.0)
-
- @unittest.skipIf(TRAVIS, "fails on Travis")
- @unittest.skipIf(not HAS_CPU_FREQ, "not supported")
- def test_cpu_freq_no_scaling_cur_freq_file(self):
- # See: https://github.com/giampaolo/psutil/issues/1071
- def open_mock(name, *args, **kwargs):
- if name.endswith('/scaling_cur_freq'):
- raise IOError(errno.ENOENT, "")
- elif name.endswith('/cpuinfo_cur_freq'):
- return io.BytesIO(b"200000")
- else:
- return orig_open(name, *args, **kwargs)
-
- orig_open = open
- patch_point = 'builtins.open' if PY3 else '__builtin__.open'
- policies = ['/sys/devices/system/cpu/cpufreq/policy0',
- '/sys/devices/system/cpu/cpufreq/policy1',
- '/sys/devices/system/cpu/cpufreq/policy2']
-
- with mock.patch(patch_point, side_effect=open_mock):
- with mock.patch('glob.glob', return_value=policies):
- freq = psutil.cpu_freq()
- self.assertEqual(freq.current, 200)
-
- # Also test that NotImplementedError is raised in case no
- # current freq file is present.
-
- def open_mock(name, *args, **kwargs):
- if name.endswith('/scaling_cur_freq'):
- raise IOError(errno.ENOENT, "")
- elif name.endswith('/cpuinfo_cur_freq'):
- raise IOError(errno.ENOENT, "")
- else:
- return orig_open(name, *args, **kwargs)
-
- orig_open = open
- patch_point = 'builtins.open' if PY3 else '__builtin__.open'
- with mock.patch(patch_point, side_effect=open_mock):
- with mock.patch('glob.glob', return_value=policies):
- self.assertRaises(NotImplementedError, psutil.cpu_freq)
-
-
-# =====================================================================
-# --- system CPU stats
-# =====================================================================
-
-
-@unittest.skipIf(not LINUX, "LINUX only")
-class TestSystemCPUStats(unittest.TestCase):
-
- @unittest.skipIf(TRAVIS, "fails on Travis")
- def test_ctx_switches(self):
- vmstat_value = vmstat("context switches")
- psutil_value = psutil.cpu_stats().ctx_switches
- self.assertAlmostEqual(vmstat_value, psutil_value, delta=500)
-
- @unittest.skipIf(TRAVIS, "fails on Travis")
- def test_interrupts(self):
- vmstat_value = vmstat("interrupts")
- psutil_value = psutil.cpu_stats().interrupts
- self.assertAlmostEqual(vmstat_value, psutil_value, delta=500)
-
-
-# =====================================================================
-# --- system network
-# =====================================================================
-
-
-@unittest.skipIf(not LINUX, "LINUX only")
-class TestSystemNetwork(unittest.TestCase):
-
- def test_net_if_addrs_ips(self):
- for name, addrs in psutil.net_if_addrs().items():
- for addr in addrs:
- if addr.family == psutil.AF_LINK:
- self.assertEqual(addr.address, get_mac_address(name))
- elif addr.family == socket.AF_INET:
- self.assertEqual(addr.address, get_ipv4_address(name))
- # TODO: test for AF_INET6 family
-
- def test_net_if_stats(self):
- for name, stats in psutil.net_if_stats().items():
- try:
- out = sh("ifconfig %s" % name)
- except RuntimeError:
- pass
- else:
- # Not always reliable.
- # self.assertEqual(stats.isup, 'RUNNING' in out, msg=out)
- self.assertEqual(stats.mtu,
- int(re.findall(r'(?i)MTU[: ](\d+)', out)[0]))
-
- @retry_before_failing()
- def test_net_io_counters(self):
- def ifconfig(nic):
- ret = {}
- out = sh("ifconfig %s" % name)
- ret['packets_recv'] = int(
- re.findall(r'RX packets[: ](\d+)', out)[0])
- ret['packets_sent'] = int(
- re.findall(r'TX packets[: ](\d+)', out)[0])
- ret['errin'] = int(re.findall(r'errors[: ](\d+)', out)[0])
- ret['errout'] = int(re.findall(r'errors[: ](\d+)', out)[1])
- ret['dropin'] = int(re.findall(r'dropped[: ](\d+)', out)[0])
- ret['dropout'] = int(re.findall(r'dropped[: ](\d+)', out)[1])
- ret['bytes_recv'] = int(
- re.findall(r'RX (?:packets \d+ +)?bytes[: ](\d+)', out)[0])
- ret['bytes_sent'] = int(
- re.findall(r'TX (?:packets \d+ +)?bytes[: ](\d+)', out)[0])
- return ret
-
- nio = psutil.net_io_counters(pernic=True, nowrap=False)
- for name, stats in nio.items():
- try:
- ifconfig_ret = ifconfig(name)
- except RuntimeError:
- continue
- self.assertAlmostEqual(
- stats.bytes_recv, ifconfig_ret['bytes_recv'], delta=1024 * 5)
- self.assertAlmostEqual(
- stats.bytes_sent, ifconfig_ret['bytes_sent'], delta=1024 * 5)
- self.assertAlmostEqual(
- stats.packets_recv, ifconfig_ret['packets_recv'], delta=1024)
- self.assertAlmostEqual(
- stats.packets_sent, ifconfig_ret['packets_sent'], delta=1024)
- self.assertAlmostEqual(
- stats.errin, ifconfig_ret['errin'], delta=10)
- self.assertAlmostEqual(
- stats.errout, ifconfig_ret['errout'], delta=10)
- self.assertAlmostEqual(
- stats.dropin, ifconfig_ret['dropin'], delta=10)
- self.assertAlmostEqual(
- stats.dropout, ifconfig_ret['dropout'], delta=10)
-
- # XXX - not reliable when having virtual NICs installed by Docker.
- # @unittest.skipIf(not which('ip'), "'ip' utility not available")
- # @unittest.skipIf(TRAVIS, "skipped on Travis")
- # def test_net_if_names(self):
- # out = sh("ip addr").strip()
- # nics = [x for x in psutil.net_if_addrs().keys() if ':' not in x]
- # found = 0
- # for line in out.split('\n'):
- # line = line.strip()
- # if re.search(r"^\d+:", line):
- # found += 1
- # name = line.split(':')[1].strip()
- # self.assertIn(name, nics)
- # self.assertEqual(len(nics), found, msg="%s\n---\n%s" % (
- # pprint.pformat(nics), out))
-
- @mock.patch('psutil._pslinux.socket.inet_ntop', side_effect=ValueError)
- @mock.patch('psutil._pslinux.supports_ipv6', return_value=False)
- def test_net_connections_ipv6_unsupported(self, supports_ipv6, inet_ntop):
- # see: https://github.com/giampaolo/psutil/issues/623
- try:
- s = socket.socket(socket.AF_INET6, socket.SOCK_STREAM)
- self.addCleanup(s.close)
- s.bind(("::1", 0))
- except socket.error:
- pass
- psutil.net_connections(kind='inet6')
-
- def test_net_connections_mocked(self):
- with mock_open_content(
- '/proc/net/unix',
- textwrap.dedent("""\
- 0: 00000003 000 000 0001 03 462170 @/tmp/dbus-Qw2hMPIU3n
- 0: 00000003 000 000 0001 03 35010 @/tmp/dbus-tB2X8h69BQ
- 0: 00000003 000 000 0001 03 34424 @/tmp/dbus-cHy80Y8O
- 000000000000000000000000000000000000000000000000000000
- """)) as m:
- psutil.net_connections(kind='unix')
- assert m.called
-
-
-# =====================================================================
-# --- system disk
-# =====================================================================
-
-
-@unittest.skipIf(not LINUX, "LINUX only")
-class TestSystemDisks(unittest.TestCase):
-
- @unittest.skipIf(not hasattr(os, 'statvfs'), "os.statvfs() not available")
- @skip_on_not_implemented()
- def test_disk_partitions_and_usage(self):
- # test psutil.disk_usage() and psutil.disk_partitions()
- # against "df -a"
- def df(path):
- out = sh('df -P -B 1 "%s"' % path).strip()
- lines = out.split('\n')
- lines.pop(0)
- line = lines.pop(0)
- dev, total, used, free = line.split()[:4]
- if dev == 'none':
- dev = ''
- total, used, free = int(total), int(used), int(free)
- return dev, total, used, free
-
- for part in psutil.disk_partitions(all=False):
- usage = psutil.disk_usage(part.mountpoint)
- dev, total, used, free = df(part.mountpoint)
- self.assertEqual(usage.total, total)
- # 10 MB tollerance
- if abs(usage.free - free) > 10 * 1024 * 1024:
- self.fail("psutil=%s, df=%s" % (usage.free, free))
- if abs(usage.used - used) > 10 * 1024 * 1024:
- self.fail("psutil=%s, df=%s" % (usage.used, used))
-
- def test_disk_partitions_mocked(self):
- # Test that ZFS partitions are returned.
- with open("/proc/filesystems", "r") as f:
- data = f.read()
- if 'zfs' in data:
- for part in psutil.disk_partitions():
- if part.fstype == 'zfs':
- break
- else:
- self.fail("couldn't find any ZFS partition")
- else:
- # No ZFS partitions on this system. Let's fake one.
- fake_file = io.StringIO(u("nodev\tzfs\n"))
- with mock.patch('psutil._pslinux.open',
- return_value=fake_file, create=True) as m1:
- with mock.patch(
- 'psutil._pslinux.cext.disk_partitions',
- return_value=[('/dev/sdb3', '/', 'zfs', 'rw')]) as m2:
- ret = psutil.disk_partitions()
- assert m1.called
- assert m2.called
- assert ret
- self.assertEqual(ret[0].fstype, 'zfs')
-
- def test_disk_io_counters_kernel_2_4_mocked(self):
- # Tests /proc/diskstats parsing format for 2.4 kernels, see:
- # https://github.com/giampaolo/psutil/issues/767
- with mock_open_content(
- '/proc/diskstats',
- " 3 0 1 hda 2 3 4 5 6 7 8 9 10 11 12"):
- with mock.patch('psutil._pslinux.is_storage_device',
- return_value=True):
- ret = psutil.disk_io_counters(nowrap=False)
- self.assertEqual(ret.read_count, 1)
- self.assertEqual(ret.read_merged_count, 2)
- self.assertEqual(ret.read_bytes, 3 * SECTOR_SIZE)
- self.assertEqual(ret.read_time, 4)
- self.assertEqual(ret.write_count, 5)
- self.assertEqual(ret.write_merged_count, 6)
- self.assertEqual(ret.write_bytes, 7 * SECTOR_SIZE)
- self.assertEqual(ret.write_time, 8)
- self.assertEqual(ret.busy_time, 10)
-
- def test_disk_io_counters_kernel_2_6_full_mocked(self):
- # Tests /proc/diskstats parsing format for 2.6 kernels,
- # lines reporting all metrics:
- # https://github.com/giampaolo/psutil/issues/767
- with mock_open_content(
- '/proc/diskstats',
- " 3 0 hda 1 2 3 4 5 6 7 8 9 10 11"):
- with mock.patch('psutil._pslinux.is_storage_device',
- return_value=True):
- ret = psutil.disk_io_counters(nowrap=False)
- self.assertEqual(ret.read_count, 1)
- self.assertEqual(ret.read_merged_count, 2)
- self.assertEqual(ret.read_bytes, 3 * SECTOR_SIZE)
- self.assertEqual(ret.read_time, 4)
- self.assertEqual(ret.write_count, 5)
- self.assertEqual(ret.write_merged_count, 6)
- self.assertEqual(ret.write_bytes, 7 * SECTOR_SIZE)
- self.assertEqual(ret.write_time, 8)
- self.assertEqual(ret.busy_time, 10)
-
- def test_disk_io_counters_kernel_2_6_limited_mocked(self):
- # Tests /proc/diskstats parsing format for 2.6 kernels,
- # where one line of /proc/partitions return a limited
- # amount of metrics when it bumps into a partition
- # (instead of a disk). See:
- # https://github.com/giampaolo/psutil/issues/767
- with mock_open_content(
- '/proc/diskstats',
- " 3 1 hda 1 2 3 4"):
- with mock.patch('psutil._pslinux.is_storage_device',
- return_value=True):
- ret = psutil.disk_io_counters(nowrap=False)
- self.assertEqual(ret.read_count, 1)
- self.assertEqual(ret.read_bytes, 2 * SECTOR_SIZE)
- self.assertEqual(ret.write_count, 3)
- self.assertEqual(ret.write_bytes, 4 * SECTOR_SIZE)
-
- self.assertEqual(ret.read_merged_count, 0)
- self.assertEqual(ret.read_time, 0)
- self.assertEqual(ret.write_merged_count, 0)
- self.assertEqual(ret.write_time, 0)
- self.assertEqual(ret.busy_time, 0)
-
- def test_disk_io_counters_include_partitions(self):
- # Make sure that when perdisk=True disk partitions are returned,
- # see:
- # https://github.com/giampaolo/psutil/pull/1313#issuecomment-408626842
- with mock_open_content(
- '/proc/diskstats',
- textwrap.dedent("""\
- 3 0 nvme0n1 1 2 3 4 5 6 7 8 9 10 11
- 3 0 nvme0n1p1 1 2 3 4 5 6 7 8 9 10 11
- """)):
- with mock.patch('psutil._pslinux.is_storage_device',
- return_value=False):
- ret = psutil.disk_io_counters(perdisk=True, nowrap=False)
- self.assertEqual(len(ret), 2)
- self.assertEqual(ret['nvme0n1'].read_count, 1)
- self.assertEqual(ret['nvme0n1p1'].read_count, 1)
- self.assertEqual(ret['nvme0n1'].write_count, 5)
- self.assertEqual(ret['nvme0n1p1'].write_count, 5)
-
- def test_disk_io_counters_exclude_partitions(self):
- # Make sure that when perdisk=False partitions (e.g. 'sda1',
- # 'nvme0n1p1') are skipped and not included in the total count.
- # https://github.com/giampaolo/psutil/pull/1313#issuecomment-408626842
- with mock_open_content(
- '/proc/diskstats',
- textwrap.dedent("""\
- 3 0 nvme0n1 1 2 3 4 5 6 7 8 9 10 11
- 3 0 nvme0n1p1 1 2 3 4 5 6 7 8 9 10 11
- """)):
- with mock.patch('psutil._pslinux.is_storage_device',
- return_value=False):
- ret = psutil.disk_io_counters(perdisk=False, nowrap=False)
- self.assertIsNone(ret)
-
- #
- def is_storage_device(name):
- return name == 'nvme0n1'
-
- with mock_open_content(
- '/proc/diskstats',
- textwrap.dedent("""\
- 3 0 nvme0n1 1 2 3 4 5 6 7 8 9 10 11
- 3 0 nvme0n1p1 1 2 3 4 5 6 7 8 9 10 11
- """)):
- with mock.patch('psutil._pslinux.is_storage_device',
- create=True, side_effect=is_storage_device):
- ret = psutil.disk_io_counters(perdisk=False, nowrap=False)
- self.assertEqual(ret.read_count, 1)
- self.assertEqual(ret.write_count, 5)
-
- def test_disk_io_counters_sysfs(self):
- def exists(path):
- if path == '/proc/diskstats':
- return False
- return True
-
- wprocfs = psutil.disk_io_counters(perdisk=True)
- with mock.patch('psutil._pslinux.os.path.exists',
- create=True, side_effect=exists):
- wsysfs = psutil.disk_io_counters(perdisk=True)
- self.assertEqual(len(wprocfs), len(wsysfs))
-
- def test_disk_io_counters_not_impl(self):
- def exists(path):
- return False
-
- with mock.patch('psutil._pslinux.os.path.exists',
- create=True, side_effect=exists):
- self.assertRaises(NotImplementedError, psutil.disk_io_counters)
-
-
-# =====================================================================
-# --- misc
-# =====================================================================
-
-
-@unittest.skipIf(not LINUX, "LINUX only")
-class TestMisc(unittest.TestCase):
-
- def test_boot_time(self):
- vmstat_value = vmstat('boot time')
- psutil_value = psutil.boot_time()
- self.assertEqual(int(vmstat_value), int(psutil_value))
-
- @mock.patch('psutil.traceback.print_exc')
- def test_no_procfs_on_import(self, tb):
- my_procfs = tempfile.mkdtemp()
-
- with open(os.path.join(my_procfs, 'stat'), 'w') as f:
- f.write('cpu 0 0 0 0 0 0 0 0 0 0\n')
- f.write('cpu0 0 0 0 0 0 0 0 0 0 0\n')
- f.write('cpu1 0 0 0 0 0 0 0 0 0 0\n')
-
- try:
- orig_open = open
-
- def open_mock(name, *args, **kwargs):
- if name.startswith('/proc'):
- raise IOError(errno.ENOENT, 'rejecting access for test')
- return orig_open(name, *args, **kwargs)
-
- patch_point = 'builtins.open' if PY3 else '__builtin__.open'
- with mock.patch(patch_point, side_effect=open_mock):
- reload_module(psutil)
- assert tb.called
-
- self.assertRaises(IOError, psutil.cpu_times)
- self.assertRaises(IOError, psutil.cpu_times, percpu=True)
- self.assertRaises(IOError, psutil.cpu_percent)
- self.assertRaises(IOError, psutil.cpu_percent, percpu=True)
- self.assertRaises(IOError, psutil.cpu_times_percent)
- self.assertRaises(
- IOError, psutil.cpu_times_percent, percpu=True)
-
- psutil.PROCFS_PATH = my_procfs
-
- self.assertEqual(psutil.cpu_percent(), 0)
- self.assertEqual(sum(psutil.cpu_times_percent()), 0)
-
- # since we don't know the number of CPUs at import time,
- # we awkwardly say there are none until the second call
- per_cpu_percent = psutil.cpu_percent(percpu=True)
- self.assertEqual(sum(per_cpu_percent), 0)
-
- # ditto awkward length
- per_cpu_times_percent = psutil.cpu_times_percent(percpu=True)
- self.assertEqual(sum(map(sum, per_cpu_times_percent)), 0)
-
- # much user, very busy
- with open(os.path.join(my_procfs, 'stat'), 'w') as f:
- f.write('cpu 1 0 0 0 0 0 0 0 0 0\n')
- f.write('cpu0 1 0 0 0 0 0 0 0 0 0\n')
- f.write('cpu1 1 0 0 0 0 0 0 0 0 0\n')
-
- self.assertNotEqual(psutil.cpu_percent(), 0)
- self.assertNotEqual(
- sum(psutil.cpu_percent(percpu=True)), 0)
- self.assertNotEqual(sum(psutil.cpu_times_percent()), 0)
- self.assertNotEqual(
- sum(map(sum, psutil.cpu_times_percent(percpu=True))), 0)
- finally:
- shutil.rmtree(my_procfs)
- reload_module(psutil)
-
- self.assertEqual(psutil.PROCFS_PATH, '/proc')
-
- def test_cpu_steal_decrease(self):
- # Test cumulative cpu stats decrease. We should ignore this.
- # See issue #1210.
- with mock_open_content(
- "/proc/stat",
- textwrap.dedent("""\
- cpu 0 0 0 0 0 0 0 1 0 0
- cpu0 0 0 0 0 0 0 0 1 0 0
- cpu1 0 0 0 0 0 0 0 1 0 0
- """).encode()) as m:
- # first call to "percent" functions should read the new stat file
- # and compare to the "real" file read at import time - so the
- # values are meaningless
- psutil.cpu_percent()
- assert m.called
- psutil.cpu_percent(percpu=True)
- psutil.cpu_times_percent()
- psutil.cpu_times_percent(percpu=True)
-
- with mock_open_content(
- "/proc/stat",
- textwrap.dedent("""\
- cpu 1 0 0 0 0 0 0 0 0 0
- cpu0 1 0 0 0 0 0 0 0 0 0
- cpu1 1 0 0 0 0 0 0 0 0 0
- """).encode()) as m:
- # Increase "user" while steal goes "backwards" to zero.
- cpu_percent = psutil.cpu_percent()
- assert m.called
- cpu_percent_percpu = psutil.cpu_percent(percpu=True)
- cpu_times_percent = psutil.cpu_times_percent()
- cpu_times_percent_percpu = psutil.cpu_times_percent(percpu=True)
- self.assertNotEqual(cpu_percent, 0)
- self.assertNotEqual(sum(cpu_percent_percpu), 0)
- self.assertNotEqual(sum(cpu_times_percent), 0)
- self.assertNotEqual(sum(cpu_times_percent), 100.0)
- self.assertNotEqual(sum(map(sum, cpu_times_percent_percpu)), 0)
- self.assertNotEqual(sum(map(sum, cpu_times_percent_percpu)), 100.0)
- self.assertEqual(cpu_times_percent.steal, 0)
- self.assertNotEqual(cpu_times_percent.user, 0)
-
- def test_boot_time_mocked(self):
- with mock.patch('psutil._pslinux.open', create=True) as m:
- self.assertRaises(
- RuntimeError,
- psutil._pslinux.boot_time)
- assert m.called
-
- def test_users_mocked(self):
- # Make sure ':0' and ':0.0' (returned by C ext) are converted
- # to 'localhost'.
- with mock.patch('psutil._pslinux.cext.users',
- return_value=[('giampaolo', 'pts/2', ':0',
- 1436573184.0, True, 2)]) as m:
- self.assertEqual(psutil.users()[0].host, 'localhost')
- assert m.called
- with mock.patch('psutil._pslinux.cext.users',
- return_value=[('giampaolo', 'pts/2', ':0.0',
- 1436573184.0, True, 2)]) as m:
- self.assertEqual(psutil.users()[0].host, 'localhost')
- assert m.called
- # ...otherwise it should be returned as-is
- with mock.patch('psutil._pslinux.cext.users',
- return_value=[('giampaolo', 'pts/2', 'foo',
- 1436573184.0, True, 2)]) as m:
- self.assertEqual(psutil.users()[0].host, 'foo')
- assert m.called
-
- def test_procfs_path(self):
- tdir = tempfile.mkdtemp()
- try:
- psutil.PROCFS_PATH = tdir
- self.assertRaises(IOError, psutil.virtual_memory)
- self.assertRaises(IOError, psutil.cpu_times)
- self.assertRaises(IOError, psutil.cpu_times, percpu=True)
- self.assertRaises(IOError, psutil.boot_time)
- # self.assertRaises(IOError, psutil.pids)
- self.assertRaises(IOError, psutil.net_connections)
- self.assertRaises(IOError, psutil.net_io_counters)
- self.assertRaises(IOError, psutil.net_if_stats)
- # self.assertRaises(IOError, psutil.disk_io_counters)
- self.assertRaises(IOError, psutil.disk_partitions)
- self.assertRaises(psutil.NoSuchProcess, psutil.Process)
- finally:
- psutil.PROCFS_PATH = "/proc"
- os.rmdir(tdir)
-
- def test_issue_687(self):
- # In case of thread ID:
- # - pid_exists() is supposed to return False
- # - Process(tid) is supposed to work
- # - pids() should not return the TID
- # See: https://github.com/giampaolo/psutil/issues/687
- t = ThreadTask()
- t.start()
- try:
- p = psutil.Process()
- tid = p.threads()[1].id
- assert not psutil.pid_exists(tid), tid
- pt = psutil.Process(tid)
- pt.as_dict()
- self.assertNotIn(tid, psutil.pids())
- finally:
- t.stop()
-
- def test_pid_exists_no_proc_status(self):
- # Internally pid_exists relies on /proc/{pid}/status.
- # Emulate a case where this file is empty in which case
- # psutil is supposed to fall back on using pids().
- with mock_open_content("/proc/%s/status", "") as m:
- assert psutil.pid_exists(os.getpid())
- assert m.called
-
-
-# =====================================================================
-# --- sensors
-# =====================================================================
-
-
-@unittest.skipIf(not LINUX, "LINUX only")
-@unittest.skipIf(not HAS_BATTERY, "no battery")
-class TestSensorsBattery(unittest.TestCase):
-
- @unittest.skipIf(not which("acpi"), "acpi utility not available")
- def test_percent(self):
- out = sh("acpi -b")
- acpi_value = int(out.split(",")[1].strip().replace('%', ''))
- psutil_value = psutil.sensors_battery().percent
- self.assertAlmostEqual(acpi_value, psutil_value, delta=1)
-
- @unittest.skipIf(not which("acpi"), "acpi utility not available")
- def test_power_plugged(self):
- out = sh("acpi -b")
- if 'unknown' in out.lower():
- return unittest.skip("acpi output not reliable")
- if 'discharging at zero rate' in out:
- plugged = True
- else:
- plugged = "Charging" in out.split('\n')[0]
- self.assertEqual(psutil.sensors_battery().power_plugged, plugged)
-
- def test_emulate_power_plugged(self):
- # Pretend the AC power cable is connected.
- def open_mock(name, *args, **kwargs):
- if name.endswith("AC0/online") or name.endswith("AC/online"):
- return io.BytesIO(b"1")
- else:
- return orig_open(name, *args, **kwargs)
-
- orig_open = open
- patch_point = 'builtins.open' if PY3 else '__builtin__.open'
- with mock.patch(patch_point, side_effect=open_mock) as m:
- self.assertEqual(psutil.sensors_battery().power_plugged, True)
- self.assertEqual(
- psutil.sensors_battery().secsleft, psutil.POWER_TIME_UNLIMITED)
- assert m.called
-
- def test_emulate_power_plugged_2(self):
- # Same as above but pretend /AC0/online does not exist in which
- # case code relies on /status file.
- def open_mock(name, *args, **kwargs):
- if name.endswith("AC0/online") or name.endswith("AC/online"):
- raise IOError(errno.ENOENT, "")
- elif name.endswith("/status"):
- return io.StringIO(u("charging"))
- else:
- return orig_open(name, *args, **kwargs)
-
- orig_open = open
- patch_point = 'builtins.open' if PY3 else '__builtin__.open'
- with mock.patch(patch_point, side_effect=open_mock) as m:
- self.assertEqual(psutil.sensors_battery().power_plugged, True)
- assert m.called
-
- def test_emulate_power_not_plugged(self):
- # Pretend the AC power cable is not connected.
- def open_mock(name, *args, **kwargs):
- if name.endswith("AC0/online") or name.endswith("AC/online"):
- return io.BytesIO(b"0")
- else:
- return orig_open(name, *args, **kwargs)
-
- orig_open = open
- patch_point = 'builtins.open' if PY3 else '__builtin__.open'
- with mock.patch(patch_point, side_effect=open_mock) as m:
- self.assertEqual(psutil.sensors_battery().power_plugged, False)
- assert m.called
-
- def test_emulate_power_not_plugged_2(self):
- # Same as above but pretend /AC0/online does not exist in which
- # case code relies on /status file.
- def open_mock(name, *args, **kwargs):
- if name.endswith("AC0/online") or name.endswith("AC/online"):
- raise IOError(errno.ENOENT, "")
- elif name.endswith("/status"):
- return io.StringIO(u("discharging"))
- else:
- return orig_open(name, *args, **kwargs)
-
- orig_open = open
- patch_point = 'builtins.open' if PY3 else '__builtin__.open'
- with mock.patch(patch_point, side_effect=open_mock) as m:
- self.assertEqual(psutil.sensors_battery().power_plugged, False)
- assert m.called
-
- def test_emulate_power_undetermined(self):
- # Pretend we can't know whether the AC power cable not
- # connected (assert fallback to False).
- def open_mock(name, *args, **kwargs):
- if name.startswith("/sys/class/power_supply/AC0/online") or \
- name.startswith("/sys/class/power_supply/AC/online"):
- raise IOError(errno.ENOENT, "")
- elif name.startswith("/sys/class/power_supply/BAT0/status"):
- return io.BytesIO(b"???")
- else:
- return orig_open(name, *args, **kwargs)
-
- orig_open = open
- patch_point = 'builtins.open' if PY3 else '__builtin__.open'
- with mock.patch(patch_point, side_effect=open_mock) as m:
- self.assertIsNone(psutil.sensors_battery().power_plugged)
- assert m.called
-
- def test_emulate_no_base_files(self):
- # Emulate a case where base metrics files are not present,
- # in which case we're supposed to get None.
- with mock_open_exception(
- "/sys/class/power_supply/BAT0/energy_now",
- IOError(errno.ENOENT, "")):
- with mock_open_exception(
- "/sys/class/power_supply/BAT0/charge_now",
- IOError(errno.ENOENT, "")):
- self.assertIsNone(psutil.sensors_battery())
-
- def test_emulate_energy_full_0(self):
- # Emulate a case where energy_full files returns 0.
- with mock_open_content(
- "/sys/class/power_supply/BAT0/energy_full", b"0") as m:
- self.assertEqual(psutil.sensors_battery().percent, 0)
- assert m.called
-
- def test_emulate_energy_full_not_avail(self):
- # Emulate a case where energy_full file does not exist.
- # Expected fallback on /capacity.
- with mock_open_exception(
- "/sys/class/power_supply/BAT0/energy_full",
- IOError(errno.ENOENT, "")):
- with mock_open_exception(
- "/sys/class/power_supply/BAT0/charge_full",
- IOError(errno.ENOENT, "")):
- with mock_open_content(
- "/sys/class/power_supply/BAT0/capacity", b"88"):
- self.assertEqual(psutil.sensors_battery().percent, 88)
-
- def test_emulate_no_power(self):
- # Emulate a case where /AC0/online file nor /BAT0/status exist.
- with mock_open_exception(
- "/sys/class/power_supply/AC/online",
- IOError(errno.ENOENT, "")):
- with mock_open_exception(
- "/sys/class/power_supply/AC0/online",
- IOError(errno.ENOENT, "")):
- with mock_open_exception(
- "/sys/class/power_supply/BAT0/status",
- IOError(errno.ENOENT, "")):
- self.assertIsNone(psutil.sensors_battery().power_plugged)
-
-
-@unittest.skipIf(not LINUX, "LINUX only")
-class TestSensorsTemperatures(unittest.TestCase):
-
- @unittest.skipIf(TRAVIS, "unreliable on TRAVIS")
- def test_emulate_eio_error(self):
- def open_mock(name, *args, **kwargs):
- if name.endswith("_input"):
- raise OSError(errno.EIO, "")
- else:
- return orig_open(name, *args, **kwargs)
-
- orig_open = open
- patch_point = 'builtins.open' if PY3 else '__builtin__.open'
- with mock.patch(patch_point, side_effect=open_mock) as m:
- with warnings.catch_warnings(record=True) as ws:
- self.assertEqual(psutil.sensors_temperatures(), {})
- assert m.called
- self.assertIn("ignoring", str(ws[0].message))
-
- def test_emulate_data(self):
- def open_mock(name, *args, **kwargs):
- if name.endswith('/name'):
- return io.StringIO(u("name"))
- elif name.endswith('/temp1_label'):
- return io.StringIO(u("label"))
- elif name.endswith('/temp1_input'):
- return io.BytesIO(b"30000")
- elif name.endswith('/temp1_max'):
- return io.BytesIO(b"40000")
- elif name.endswith('/temp1_crit'):
- return io.BytesIO(b"50000")
- else:
- return orig_open(name, *args, **kwargs)
-
- orig_open = open
- patch_point = 'builtins.open' if PY3 else '__builtin__.open'
- with mock.patch(patch_point, side_effect=open_mock):
- with mock.patch('glob.glob',
- return_value=['/sys/class/hwmon/hwmon0/temp1']):
- temp = psutil.sensors_temperatures()['name'][0]
- self.assertEqual(temp.label, 'label')
- self.assertEqual(temp.current, 30.0)
- self.assertEqual(temp.high, 40.0)
- self.assertEqual(temp.critical, 50.0)
-
-
-@unittest.skipIf(not LINUX, "LINUX only")
-class TestSensorsFans(unittest.TestCase):
-
- def test_emulate_data(self):
- def open_mock(name, *args, **kwargs):
- if name.endswith('/name'):
- return io.StringIO(u("name"))
- elif name.endswith('/fan1_label'):
- return io.StringIO(u("label"))
- elif name.endswith('/fan1_input'):
- return io.StringIO(u("2000"))
- else:
- return orig_open(name, *args, **kwargs)
-
- orig_open = open
- patch_point = 'builtins.open' if PY3 else '__builtin__.open'
- with mock.patch(patch_point, side_effect=open_mock):
- with mock.patch('glob.glob',
- return_value=['/sys/class/hwmon/hwmon2/fan1']):
- fan = psutil.sensors_fans()['name'][0]
- self.assertEqual(fan.label, 'label')
- self.assertEqual(fan.current, 2000)
-
-
-# =====================================================================
-# --- test process
-# =====================================================================
-
-
-@unittest.skipIf(not LINUX, "LINUX only")
-class TestProcess(unittest.TestCase):
-
- def setUp(self):
- safe_rmpath(TESTFN)
-
- tearDown = setUp
-
- def test_memory_full_info(self):
- src = textwrap.dedent("""
- import time
- with open("%s", "w") as f:
- time.sleep(10)
- """ % TESTFN)
- sproc = pyrun(src)
- self.addCleanup(reap_children)
- call_until(lambda: os.listdir('.'), "'%s' not in ret" % TESTFN)
- p = psutil.Process(sproc.pid)
- time.sleep(.1)
- mem = p.memory_full_info()
- maps = p.memory_maps(grouped=False)
- self.assertAlmostEqual(
- mem.uss, sum([x.private_dirty + x.private_clean for x in maps]),
- delta=4096)
- self.assertAlmostEqual(
- mem.pss, sum([x.pss for x in maps]), delta=4096)
- self.assertAlmostEqual(
- mem.swap, sum([x.swap for x in maps]), delta=4096)
-
- def test_memory_full_info_mocked(self):
- # See: https://github.com/giampaolo/psutil/issues/1222
- with mock_open_content(
- "/proc/%s/smaps" % os.getpid(),
- textwrap.dedent("""\
- fffff0 r-xp 00000000 00:00 0 [vsyscall]
- Size: 1 kB
- Rss: 2 kB
- Pss: 3 kB
- Shared_Clean: 4 kB
- Shared_Dirty: 5 kB
- Private_Clean: 6 kB
- Private_Dirty: 7 kB
- Referenced: 8 kB
- Anonymous: 9 kB
- LazyFree: 10 kB
- AnonHugePages: 11 kB
- ShmemPmdMapped: 12 kB
- Shared_Hugetlb: 13 kB
- Private_Hugetlb: 14 kB
- Swap: 15 kB
- SwapPss: 16 kB
- KernelPageSize: 17 kB
- MMUPageSize: 18 kB
- Locked: 19 kB
- VmFlags: rd ex
- """).encode()) as m:
- p = psutil.Process()
- mem = p.memory_full_info()
- assert m.called
- self.assertEqual(mem.uss, (6 + 7 + 14) * 1024)
- self.assertEqual(mem.pss, 3 * 1024)
- self.assertEqual(mem.swap, 15 * 1024)
-
- # On PYPY file descriptors are not closed fast enough.
- @unittest.skipIf(PYPY, "unreliable on PYPY")
- def test_open_files_mode(self):
- def get_test_file():
- p = psutil.Process()
- giveup_at = time.time() + 2
- while True:
- for file in p.open_files():
- if file.path == os.path.abspath(TESTFN):
- return file
- elif time.time() > giveup_at:
- break
- raise RuntimeError("timeout looking for test file")
-
- #
- with open(TESTFN, "w"):
- self.assertEqual(get_test_file().mode, "w")
- with open(TESTFN, "r"):
- self.assertEqual(get_test_file().mode, "r")
- with open(TESTFN, "a"):
- self.assertEqual(get_test_file().mode, "a")
- #
- with open(TESTFN, "r+"):
- self.assertEqual(get_test_file().mode, "r+")
- with open(TESTFN, "w+"):
- self.assertEqual(get_test_file().mode, "r+")
- with open(TESTFN, "a+"):
- self.assertEqual(get_test_file().mode, "a+")
- # note: "x" bit is not supported
- if PY3:
- safe_rmpath(TESTFN)
- with open(TESTFN, "x"):
- self.assertEqual(get_test_file().mode, "w")
- safe_rmpath(TESTFN)
- with open(TESTFN, "x+"):
- self.assertEqual(get_test_file().mode, "r+")
-
- def test_open_files_file_gone(self):
- # simulates a file which gets deleted during open_files()
- # execution
- p = psutil.Process()
- files = p.open_files()
- with tempfile.NamedTemporaryFile():
- # give the kernel some time to see the new file
- call_until(p.open_files, "len(ret) != %i" % len(files))
- with mock.patch('psutil._pslinux.os.readlink',
- side_effect=OSError(errno.ENOENT, "")) as m:
- files = p.open_files()
- assert not files
- assert m.called
- # also simulate the case where os.readlink() returns EINVAL
- # in which case psutil is supposed to 'continue'
- with mock.patch('psutil._pslinux.os.readlink',
- side_effect=OSError(errno.EINVAL, "")) as m:
- self.assertEqual(p.open_files(), [])
- assert m.called
-
- def test_open_files_fd_gone(self):
- # Simulate a case where /proc/{pid}/fdinfo/{fd} disappears
- # while iterating through fds.
- # https://travis-ci.org/giampaolo/psutil/jobs/225694530
- p = psutil.Process()
- files = p.open_files()
- with tempfile.NamedTemporaryFile():
- # give the kernel some time to see the new file
- call_until(p.open_files, "len(ret) != %i" % len(files))
- patch_point = 'builtins.open' if PY3 else '__builtin__.open'
- with mock.patch(patch_point,
- side_effect=IOError(errno.ENOENT, "")) as m:
- files = p.open_files()
- assert not files
- assert m.called
-
- # --- mocked tests
-
- def test_terminal_mocked(self):
- with mock.patch('psutil._pslinux._psposix.get_terminal_map',
- return_value={}) as m:
- self.assertIsNone(psutil._pslinux.Process(os.getpid()).terminal())
- assert m.called
-
- # TODO: re-enable this test.
- # def test_num_ctx_switches_mocked(self):
- # with mock.patch('psutil._pslinux.open', create=True) as m:
- # self.assertRaises(
- # NotImplementedError,
- # psutil._pslinux.Process(os.getpid()).num_ctx_switches)
- # assert m.called
-
- def test_cmdline_mocked(self):
- # see: https://github.com/giampaolo/psutil/issues/639
- p = psutil.Process()
- fake_file = io.StringIO(u('foo\x00bar\x00'))
- with mock.patch('psutil._pslinux.open',
- return_value=fake_file, create=True) as m:
- self.assertEqual(p.cmdline(), ['foo', 'bar'])
- assert m.called
- fake_file = io.StringIO(u('foo\x00bar\x00\x00'))
- with mock.patch('psutil._pslinux.open',
- return_value=fake_file, create=True) as m:
- self.assertEqual(p.cmdline(), ['foo', 'bar', ''])
- assert m.called
-
- def test_cmdline_spaces_mocked(self):
- # see: https://github.com/giampaolo/psutil/issues/1179
- p = psutil.Process()
- fake_file = io.StringIO(u('foo bar '))
- with mock.patch('psutil._pslinux.open',
- return_value=fake_file, create=True) as m:
- self.assertEqual(p.cmdline(), ['foo', 'bar'])
- assert m.called
- fake_file = io.StringIO(u('foo bar '))
- with mock.patch('psutil._pslinux.open',
- return_value=fake_file, create=True) as m:
- self.assertEqual(p.cmdline(), ['foo', 'bar', ''])
- assert m.called
-
- def test_readlink_path_deleted_mocked(self):
- with mock.patch('psutil._pslinux.os.readlink',
- return_value='/home/foo (deleted)'):
- self.assertEqual(psutil.Process().exe(), "/home/foo")
- self.assertEqual(psutil.Process().cwd(), "/home/foo")
-
- def test_threads_mocked(self):
- # Test the case where os.listdir() returns a file (thread)
- # which no longer exists by the time we open() it (race
- # condition). threads() is supposed to ignore that instead
- # of raising NSP.
- def open_mock(name, *args, **kwargs):
- if name.startswith('/proc/%s/task' % os.getpid()):
- raise IOError(errno.ENOENT, "")
- else:
- return orig_open(name, *args, **kwargs)
-
- orig_open = open
- patch_point = 'builtins.open' if PY3 else '__builtin__.open'
- with mock.patch(patch_point, side_effect=open_mock) as m:
- ret = psutil.Process().threads()
- assert m.called
- self.assertEqual(ret, [])
-
- # ...but if it bumps into something != ENOENT we want an
- # exception.
- def open_mock(name, *args, **kwargs):
- if name.startswith('/proc/%s/task' % os.getpid()):
- raise IOError(errno.EPERM, "")
- else:
- return orig_open(name, *args, **kwargs)
-
- with mock.patch(patch_point, side_effect=open_mock):
- self.assertRaises(psutil.AccessDenied, psutil.Process().threads)
-
- def test_exe_mocked(self):
- with mock.patch('psutil._pslinux.readlink',
- side_effect=OSError(errno.ENOENT, "")) as m1:
- with mock.patch('psutil.Process.cmdline',
- side_effect=psutil.AccessDenied(0, "")) as m2:
- # No such file error; might be raised also if /proc/pid/exe
- # path actually exists for system processes with low pids
- # (about 0-20). In this case psutil is supposed to return
- # an empty string.
- ret = psutil.Process().exe()
- assert m1.called
- assert m2.called
- self.assertEqual(ret, "")
-
- # ...but if /proc/pid no longer exist we're supposed to treat
- # it as an alias for zombie process
- with mock.patch('psutil._pslinux.os.path.lexists',
- return_value=False):
- self.assertRaises(
- psutil.ZombieProcess, psutil.Process().exe)
-
- def test_issue_1014(self):
- # Emulates a case where smaps file does not exist. In this case
- # wrap_exception decorator should not raise NoSuchProcess.
- with mock_open_exception(
- '/proc/%s/smaps' % os.getpid(),
- IOError(errno.ENOENT, "")) as m:
- p = psutil.Process()
- with self.assertRaises(IOError) as err:
- p.memory_maps()
- self.assertEqual(err.exception.errno, errno.ENOENT)
- assert m.called
-
- @unittest.skipIf(not HAS_RLIMIT, "not supported")
- def test_rlimit_zombie(self):
- # Emulate a case where rlimit() raises ENOSYS, which may
- # happen in case of zombie process:
- # https://travis-ci.org/giampaolo/psutil/jobs/51368273
- with mock.patch("psutil._pslinux.cext.linux_prlimit",
- side_effect=OSError(errno.ENOSYS, "")) as m:
- p = psutil.Process()
- p.name()
- with self.assertRaises(psutil.ZombieProcess) as exc:
- p.rlimit(psutil.RLIMIT_NOFILE)
- assert m.called
- self.assertEqual(exc.exception.pid, p.pid)
- self.assertEqual(exc.exception.name, p.name())
-
- def test_cwd_zombie(self):
- with mock.patch("psutil._pslinux.os.readlink",
- side_effect=OSError(errno.ENOENT, "")) as m:
- p = psutil.Process()
- p.name()
- with self.assertRaises(psutil.ZombieProcess) as exc:
- p.cwd()
- assert m.called
- self.assertEqual(exc.exception.pid, p.pid)
- self.assertEqual(exc.exception.name, p.name())
-
- def test_stat_file_parsing(self):
- from psutil._pslinux import CLOCK_TICKS
-
- args = [
- "0", # pid
- "(cat)", # name
- "Z", # status
- "1", # ppid
- "0", # pgrp
- "0", # session
- "0", # tty
- "0", # tpgid
- "0", # flags
- "0", # minflt
- "0", # cminflt
- "0", # majflt
- "0", # cmajflt
- "2", # utime
- "3", # stime
- "4", # cutime
- "5", # cstime
- "0", # priority
- "0", # nice
- "0", # num_threads
- "0", # itrealvalue
- "6", # starttime
- "0", # vsize
- "0", # rss
- "0", # rsslim
- "0", # startcode
- "0", # endcode
- "0", # startstack
- "0", # kstkesp
- "0", # kstkeip
- "0", # signal
- "0", # blocked
- "0", # sigignore
- "0", # sigcatch
- "0", # wchan
- "0", # nswap
- "0", # cnswap
- "0", # exit_signal
- "6", # processor
- ]
- content = " ".join(args).encode()
- with mock_open_content('/proc/%s/stat' % os.getpid(), content):
- p = psutil.Process()
- self.assertEqual(p.name(), 'cat')
- self.assertEqual(p.status(), psutil.STATUS_ZOMBIE)
- self.assertEqual(p.ppid(), 1)
- self.assertEqual(
- p.create_time(), 6 / CLOCK_TICKS + psutil.boot_time())
- cpu = p.cpu_times()
- self.assertEqual(cpu.user, 2 / CLOCK_TICKS)
- self.assertEqual(cpu.system, 3 / CLOCK_TICKS)
- self.assertEqual(cpu.children_user, 4 / CLOCK_TICKS)
- self.assertEqual(cpu.children_system, 5 / CLOCK_TICKS)
- self.assertEqual(p.cpu_num(), 6)
-
- def test_status_file_parsing(self):
- with mock_open_content(
- '/proc/%s/status' % os.getpid(),
- textwrap.dedent("""\
- Uid:\t1000\t1001\t1002\t1003
- Gid:\t1004\t1005\t1006\t1007
- Threads:\t66
- Cpus_allowed:\tf
- Cpus_allowed_list:\t0-7
- voluntary_ctxt_switches:\t12
- nonvoluntary_ctxt_switches:\t13""").encode()):
- p = psutil.Process()
- self.assertEqual(p.num_ctx_switches().voluntary, 12)
- self.assertEqual(p.num_ctx_switches().involuntary, 13)
- self.assertEqual(p.num_threads(), 66)
- uids = p.uids()
- self.assertEqual(uids.real, 1000)
- self.assertEqual(uids.effective, 1001)
- self.assertEqual(uids.saved, 1002)
- gids = p.gids()
- self.assertEqual(gids.real, 1004)
- self.assertEqual(gids.effective, 1005)
- self.assertEqual(gids.saved, 1006)
- self.assertEqual(p._proc._get_eligible_cpus(), list(range(0, 8)))
-
-
-@unittest.skipIf(not LINUX, "LINUX only")
-class TestProcessAgainstStatus(unittest.TestCase):
- """/proc/pid/stat and /proc/pid/status have many values in common.
- Whenever possible, psutil uses /proc/pid/stat (it's faster).
- For all those cases we check that the value found in
- /proc/pid/stat (by psutil) matches the one found in
- /proc/pid/status.
- """
-
- @classmethod
- def setUpClass(cls):
- cls.proc = psutil.Process()
-
- def read_status_file(self, linestart):
- with psutil._psplatform.open_text(
- '/proc/%s/status' % self.proc.pid) as f:
- for line in f:
- line = line.strip()
- if line.startswith(linestart):
- value = line.partition('\t')[2]
- try:
- return int(value)
- except ValueError:
- return value
- raise ValueError("can't find %r" % linestart)
-
- def test_name(self):
- value = self.read_status_file("Name:")
- self.assertEqual(self.proc.name(), value)
-
- def test_status(self):
- value = self.read_status_file("State:")
- value = value[value.find('(') + 1:value.rfind(')')]
- value = value.replace(' ', '-')
- self.assertEqual(self.proc.status(), value)
-
- def test_ppid(self):
- value = self.read_status_file("PPid:")
- self.assertEqual(self.proc.ppid(), value)
-
- def test_num_threads(self):
- value = self.read_status_file("Threads:")
- self.assertEqual(self.proc.num_threads(), value)
-
- def test_uids(self):
- value = self.read_status_file("Uid:")
- value = tuple(map(int, value.split()[1:4]))
- self.assertEqual(self.proc.uids(), value)
-
- def test_gids(self):
- value = self.read_status_file("Gid:")
- value = tuple(map(int, value.split()[1:4]))
- self.assertEqual(self.proc.gids(), value)
-
- @retry_before_failing()
- def test_num_ctx_switches(self):
- value = self.read_status_file("voluntary_ctxt_switches:")
- self.assertEqual(self.proc.num_ctx_switches().voluntary, value)
- value = self.read_status_file("nonvoluntary_ctxt_switches:")
- self.assertEqual(self.proc.num_ctx_switches().involuntary, value)
-
- def test_cpu_affinity(self):
- value = self.read_status_file("Cpus_allowed_list:")
- if '-' in str(value):
- min_, max_ = map(int, value.split('-'))
- self.assertEqual(
- self.proc.cpu_affinity(), list(range(min_, max_ + 1)))
-
- def test_cpu_affinity_eligible_cpus(self):
- value = self.read_status_file("Cpus_allowed_list:")
- with mock.patch("psutil._pslinux.per_cpu_times") as m:
- self.proc._proc._get_eligible_cpus()
- if '-' in str(value):
- assert not m.called
- else:
- assert m.called
-
-
-# =====================================================================
-# --- test utils
-# =====================================================================
-
-
-@unittest.skipIf(not LINUX, "LINUX only")
-class TestUtils(unittest.TestCase):
-
- def test_open_text(self):
- with psutil._psplatform.open_text(__file__) as f:
- self.assertEqual(f.mode, 'rt')
-
- def test_open_binary(self):
- with psutil._psplatform.open_binary(__file__) as f:
- self.assertEqual(f.mode, 'rb')
-
- def test_readlink(self):
- with mock.patch("os.readlink", return_value="foo (deleted)") as m:
- self.assertEqual(psutil._psplatform.readlink("bar"), "foo")
- assert m.called
-
- def test_cat(self):
- fname = os.path.abspath(TESTFN)
- with open(fname, "wt") as f:
- f.write("foo ")
- self.assertEqual(psutil._psplatform.cat(TESTFN, binary=False), "foo")
- self.assertEqual(psutil._psplatform.cat(TESTFN, binary=True), b"foo")
- self.assertEqual(
- psutil._psplatform.cat(TESTFN + '??', fallback="bar"), "bar")
-
-
-if __name__ == '__main__':
- run_test_module_by_name(__file__)
diff --git a/server/www/packages/packages-darwin/x64/psutil/tests/test_memory_leaks.py b/server/www/packages/packages-darwin/x64/psutil/tests/test_memory_leaks.py
deleted file mode 100644
index ce08245..0000000
--- a/server/www/packages/packages-darwin/x64/psutil/tests/test_memory_leaks.py
+++ /dev/null
@@ -1,599 +0,0 @@
-#!/usr/bin/env python
-
-# 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.
-
-"""
-Tests for detecting function memory leaks (typically the ones
-implemented in C). It does so by calling a function many times and
-checking whether process memory usage keeps increasing between
-calls or over time.
-Note that this may produce false positives (especially on Windows
-for some reason).
-"""
-
-from __future__ import print_function
-import errno
-import functools
-import gc
-import os
-import sys
-import threading
-import time
-
-import psutil
-import psutil._common
-from psutil import LINUX
-from psutil import MACOS
-from psutil import OPENBSD
-from psutil import POSIX
-from psutil import SUNOS
-from psutil import WINDOWS
-from psutil._compat import xrange
-from psutil.tests import create_sockets
-from psutil.tests import get_test_subprocess
-from psutil.tests import HAS_CPU_AFFINITY
-from psutil.tests import HAS_CPU_FREQ
-from psutil.tests import HAS_ENVIRON
-from psutil.tests import HAS_IONICE
-from psutil.tests import HAS_MEMORY_MAPS
-from psutil.tests import HAS_PROC_CPU_NUM
-from psutil.tests import HAS_PROC_IO_COUNTERS
-from psutil.tests import HAS_RLIMIT
-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 reap_children
-from psutil.tests import run_test_module_by_name
-from psutil.tests import safe_rmpath
-from psutil.tests import skip_on_access_denied
-from psutil.tests import TESTFN
-from psutil.tests import TRAVIS
-from psutil.tests import unittest
-
-
-LOOPS = 1000
-MEMORY_TOLERANCE = 4096
-RETRY_FOR = 3
-
-SKIP_PYTHON_IMPL = True if TRAVIS else False
-cext = psutil._psplatform.cext
-thisproc = psutil.Process()
-SKIP_PYTHON_IMPL = True if TRAVIS else False
-
-
-# ===================================================================
-# utils
-# ===================================================================
-
-
-def skip_if_linux():
- return unittest.skipIf(LINUX and SKIP_PYTHON_IMPL,
- "worthless on LINUX (pure python)")
-
-
-def bytes2human(n):
- """
- http://code.activestate.com/recipes/578019
- >>> bytes2human(10000)
- '9.8K'
- >>> bytes2human(100001221)
- '95.4M'
- """
- symbols = ('K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y')
- prefix = {}
- for i, s in enumerate(symbols):
- prefix[s] = 1 << (i + 1) * 10
- for s in reversed(symbols):
- if n >= prefix[s]:
- value = float(n) / prefix[s]
- return '%.2f%s' % (value, s)
- return "%sB" % n
-
-
-class TestMemLeak(unittest.TestCase):
- """Base framework class which calls a function many times and
- produces a failure if process memory usage keeps increasing
- between calls or over time.
- """
- tolerance = MEMORY_TOLERANCE
- loops = LOOPS
- retry_for = RETRY_FOR
-
- def setUp(self):
- gc.collect()
-
- def execute(self, fun, *args, **kwargs):
- """Test a callable."""
- def call_many_times():
- for x in xrange(loops):
- self._call(fun, *args, **kwargs)
- del x
- gc.collect()
-
- tolerance = kwargs.pop('tolerance_', None) or self.tolerance
- loops = kwargs.pop('loops_', None) or self.loops
- retry_for = kwargs.pop('retry_for_', None) or self.retry_for
-
- # warm up
- for x in range(10):
- self._call(fun, *args, **kwargs)
- self.assertEqual(gc.garbage, [])
- self.assertEqual(threading.active_count(), 1)
- self.assertEqual(thisproc.children(), [])
-
- # Get 2 distinct memory samples, before and after having
- # called fun repeadetly.
- # step 1
- call_many_times()
- mem1 = self._get_mem()
- # step 2
- call_many_times()
- mem2 = self._get_mem()
-
- diff1 = mem2 - mem1
- if diff1 > tolerance:
- # This doesn't necessarily mean we have a leak yet.
- # At this point we assume that after having called the
- # function so many times the memory usage is stabilized
- # and if there are no leaks it should not increase
- # anymore.
- # Let's keep calling fun for 3 more seconds and fail if
- # we notice any difference.
- ncalls = 0
- stop_at = time.time() + retry_for
- while time.time() <= stop_at:
- self._call(fun, *args, **kwargs)
- ncalls += 1
-
- del stop_at
- gc.collect()
- mem3 = self._get_mem()
- diff2 = mem3 - mem2
-
- if mem3 > mem2:
- # failure
- extra_proc_mem = bytes2human(diff1 + diff2)
- print("exta proc mem: %s" % extra_proc_mem, file=sys.stderr)
- msg = "+%s after %s calls, +%s after another %s calls, "
- msg += "+%s extra proc mem"
- msg = msg % (
- bytes2human(diff1), loops, bytes2human(diff2), ncalls,
- extra_proc_mem)
- self.fail(msg)
-
- def execute_w_exc(self, exc, fun, *args, **kwargs):
- """Convenience function which tests a callable raising
- an exception.
- """
- def call():
- self.assertRaises(exc, fun, *args, **kwargs)
-
- self.execute(call)
-
- @staticmethod
- def _get_mem():
- # By using USS memory it seems it's less likely to bump
- # into false positives.
- if LINUX or WINDOWS or MACOS:
- return thisproc.memory_full_info().uss
- else:
- return thisproc.memory_info().rss
-
- @staticmethod
- def _call(fun, *args, **kwargs):
- fun(*args, **kwargs)
-
-
-# ===================================================================
-# Process class
-# ===================================================================
-
-
-class TestProcessObjectLeaks(TestMemLeak):
- """Test leaks of Process class methods."""
-
- proc = thisproc
-
- def test_coverage(self):
- skip = set((
- "pid", "as_dict", "children", "cpu_affinity", "cpu_percent",
- "ionice", "is_running", "kill", "memory_info_ex", "memory_percent",
- "nice", "oneshot", "parent", "rlimit", "send_signal", "suspend",
- "terminate", "wait"))
- for name in dir(psutil.Process):
- if name.startswith('_'):
- continue
- if name in skip:
- continue
- self.assertTrue(hasattr(self, "test_" + name), msg=name)
-
- @skip_if_linux()
- def test_name(self):
- self.execute(self.proc.name)
-
- @skip_if_linux()
- def test_cmdline(self):
- self.execute(self.proc.cmdline)
-
- @skip_if_linux()
- def test_exe(self):
- self.execute(self.proc.exe)
-
- @skip_if_linux()
- def test_ppid(self):
- self.execute(self.proc.ppid)
-
- @unittest.skipIf(not POSIX, "POSIX only")
- @skip_if_linux()
- def test_uids(self):
- self.execute(self.proc.uids)
-
- @unittest.skipIf(not POSIX, "POSIX only")
- @skip_if_linux()
- def test_gids(self):
- self.execute(self.proc.gids)
-
- @skip_if_linux()
- def test_status(self):
- self.execute(self.proc.status)
-
- def test_nice_get(self):
- self.execute(self.proc.nice)
-
- def test_nice_set(self):
- niceness = thisproc.nice()
- self.execute(self.proc.nice, niceness)
-
- @unittest.skipIf(not HAS_IONICE, "not supported")
- def test_ionice_get(self):
- self.execute(self.proc.ionice)
-
- @unittest.skipIf(not HAS_IONICE, "not supported")
- def test_ionice_set(self):
- if WINDOWS:
- value = thisproc.ionice()
- self.execute(self.proc.ionice, value)
- else:
- self.execute(self.proc.ionice, psutil.IOPRIO_CLASS_NONE)
- fun = functools.partial(cext.proc_ioprio_set, os.getpid(), -1, 0)
- self.execute_w_exc(OSError, fun)
-
- @unittest.skipIf(not HAS_PROC_IO_COUNTERS, "not supported")
- @skip_if_linux()
- def test_io_counters(self):
- self.execute(self.proc.io_counters)
-
- @unittest.skipIf(POSIX, "worthless on POSIX")
- def test_username(self):
- self.execute(self.proc.username)
-
- @skip_if_linux()
- def test_create_time(self):
- self.execute(self.proc.create_time)
-
- @skip_if_linux()
- @skip_on_access_denied(only_if=OPENBSD)
- def test_num_threads(self):
- self.execute(self.proc.num_threads)
-
- @unittest.skipIf(not WINDOWS, "WINDOWS only")
- def test_num_handles(self):
- self.execute(self.proc.num_handles)
-
- @unittest.skipIf(not POSIX, "POSIX only")
- @skip_if_linux()
- def test_num_fds(self):
- self.execute(self.proc.num_fds)
-
- @skip_if_linux()
- def test_num_ctx_switches(self):
- self.execute(self.proc.num_ctx_switches)
-
- @skip_if_linux()
- @skip_on_access_denied(only_if=OPENBSD)
- def test_threads(self):
- self.execute(self.proc.threads)
-
- @skip_if_linux()
- def test_cpu_times(self):
- self.execute(self.proc.cpu_times)
-
- @skip_if_linux()
- @unittest.skipIf(not HAS_PROC_CPU_NUM, "not supported")
- def test_cpu_num(self):
- self.execute(self.proc.cpu_num)
-
- @skip_if_linux()
- def test_memory_info(self):
- self.execute(self.proc.memory_info)
-
- @skip_if_linux()
- def test_memory_full_info(self):
- self.execute(self.proc.memory_full_info)
-
- @unittest.skipIf(not POSIX, "POSIX only")
- @skip_if_linux()
- def test_terminal(self):
- self.execute(self.proc.terminal)
-
- @unittest.skipIf(POSIX and SKIP_PYTHON_IMPL,
- "worthless on POSIX (pure python)")
- def test_resume(self):
- self.execute(self.proc.resume)
-
- @skip_if_linux()
- def test_cwd(self):
- self.execute(self.proc.cwd)
-
- @unittest.skipIf(not HAS_CPU_AFFINITY, "not supported")
- def test_cpu_affinity_get(self):
- self.execute(self.proc.cpu_affinity)
-
- @unittest.skipIf(not HAS_CPU_AFFINITY, "not supported")
- def test_cpu_affinity_set(self):
- affinity = thisproc.cpu_affinity()
- self.execute(self.proc.cpu_affinity, affinity)
- if not TRAVIS:
- self.execute_w_exc(ValueError, self.proc.cpu_affinity, [-1])
-
- @skip_if_linux()
- def test_open_files(self):
- safe_rmpath(TESTFN) # needed after UNIX socket test has run
- with open(TESTFN, 'w'):
- self.execute(self.proc.open_files)
-
- # MACOS implementation is unbelievably slow
- @unittest.skipIf(MACOS, "too slow on MACOS")
- @unittest.skipIf(not HAS_MEMORY_MAPS, "not supported")
- @skip_if_linux()
- def test_memory_maps(self):
- self.execute(self.proc.memory_maps)
-
- @unittest.skipIf(not LINUX, "LINUX only")
- @unittest.skipIf(not HAS_RLIMIT, "not supported")
- def test_rlimit_get(self):
- self.execute(self.proc.rlimit, psutil.RLIMIT_NOFILE)
-
- @unittest.skipIf(not LINUX, "LINUX only")
- @unittest.skipIf(not HAS_RLIMIT, "not supported")
- def test_rlimit_set(self):
- limit = thisproc.rlimit(psutil.RLIMIT_NOFILE)
- self.execute(self.proc.rlimit, psutil.RLIMIT_NOFILE, limit)
- self.execute_w_exc(OSError, self.proc.rlimit, -1)
-
- @skip_if_linux()
- # Windows implementation is based on a single system-wide
- # function (tested later).
- @unittest.skipIf(WINDOWS, "worthless on WINDOWS")
- def test_connections(self):
- # TODO: UNIX sockets are temporarily implemented by parsing
- # 'pfiles' cmd output; we don't want that part of the code to
- # be executed.
- with create_sockets():
- kind = 'inet' if SUNOS else 'all'
- self.execute(self.proc.connections, kind)
-
- @unittest.skipIf(not HAS_ENVIRON, "not supported")
- def test_environ(self):
- self.execute(self.proc.environ)
-
- @unittest.skipIf(not WINDOWS, "WINDOWS only")
- def test_proc_info(self):
- self.execute(cext.proc_info, os.getpid())
-
-
-class TestTerminatedProcessLeaks(TestProcessObjectLeaks):
- """Repeat the tests above looking for leaks occurring when dealing
- with terminated processes raising NoSuchProcess exception.
- The C functions are still invoked but will follow different code
- paths. We'll check those code paths.
- """
-
- @classmethod
- def setUpClass(cls):
- super(TestTerminatedProcessLeaks, cls).setUpClass()
- p = get_test_subprocess()
- cls.proc = psutil.Process(p.pid)
- cls.proc.kill()
- cls.proc.wait()
-
- @classmethod
- def tearDownClass(cls):
- super(TestTerminatedProcessLeaks, cls).tearDownClass()
- reap_children()
-
- def _call(self, fun, *args, **kwargs):
- try:
- fun(*args, **kwargs)
- except psutil.NoSuchProcess:
- pass
-
- if WINDOWS:
-
- def test_kill(self):
- self.execute(self.proc.kill)
-
- def test_terminate(self):
- self.execute(self.proc.terminate)
-
- def test_suspend(self):
- self.execute(self.proc.suspend)
-
- def test_resume(self):
- self.execute(self.proc.resume)
-
- def test_wait(self):
- self.execute(self.proc.wait)
-
- def test_proc_info(self):
- # test dual implementation
- def call():
- try:
- return cext.proc_info(self.proc.pid)
- except OSError as err:
- if err.errno != errno.ESRCH:
- raise
-
- self.execute(call)
-
-
-# ===================================================================
-# system APIs
-# ===================================================================
-
-
-class TestModuleFunctionsLeaks(TestMemLeak):
- """Test leaks of psutil module functions."""
-
- def test_coverage(self):
- skip = set((
- "version_info", "__version__", "process_iter", "wait_procs",
- "cpu_percent", "cpu_times_percent", "cpu_count"))
- for name in psutil.__all__:
- if not name.islower():
- continue
- if name in skip:
- continue
- self.assertTrue(hasattr(self, "test_" + name), msg=name)
-
- # --- cpu
-
- @skip_if_linux()
- def test_cpu_count_logical(self):
- self.execute(psutil.cpu_count, logical=True)
-
- @skip_if_linux()
- def test_cpu_count_physical(self):
- self.execute(psutil.cpu_count, logical=False)
-
- @skip_if_linux()
- def test_cpu_times(self):
- self.execute(psutil.cpu_times)
-
- @skip_if_linux()
- def test_per_cpu_times(self):
- self.execute(psutil.cpu_times, percpu=True)
-
- def test_cpu_stats(self):
- self.execute(psutil.cpu_stats)
-
- @skip_if_linux()
- @unittest.skipIf(not HAS_CPU_FREQ, "not supported")
- def test_cpu_freq(self):
- self.execute(psutil.cpu_freq)
-
- # --- mem
-
- def test_virtual_memory(self):
- self.execute(psutil.virtual_memory)
-
- # TODO: remove this skip when this gets fixed
- @unittest.skipIf(SUNOS,
- "worthless on SUNOS (uses a subprocess)")
- def test_swap_memory(self):
- self.execute(psutil.swap_memory)
-
- @unittest.skipIf(POSIX and SKIP_PYTHON_IMPL,
- "worthless on POSIX (pure python)")
- def test_pid_exists(self):
- self.execute(psutil.pid_exists, os.getpid())
-
- # --- disk
-
- @unittest.skipIf(POSIX and SKIP_PYTHON_IMPL,
- "worthless on POSIX (pure python)")
- def test_disk_usage(self):
- self.execute(psutil.disk_usage, '.')
-
- def test_disk_partitions(self):
- self.execute(psutil.disk_partitions)
-
- @unittest.skipIf(LINUX and not os.path.exists('/proc/diskstats'),
- '/proc/diskstats not available on this Linux version')
- @skip_if_linux()
- def test_disk_io_counters(self):
- self.execute(psutil.disk_io_counters, nowrap=False)
-
- # --- proc
-
- @skip_if_linux()
- def test_pids(self):
- self.execute(psutil.pids)
-
- # --- net
-
- @skip_if_linux()
- def test_net_io_counters(self):
- self.execute(psutil.net_io_counters, nowrap=False)
-
- @unittest.skipIf(LINUX,
- "worthless on Linux (pure python)")
- @unittest.skipIf(MACOS and os.getuid() != 0, "need root access")
- def test_net_connections(self):
- with create_sockets():
- self.execute(psutil.net_connections)
-
- def test_net_if_addrs(self):
- # Note: verified that on Windows this was a false positive.
- self.execute(psutil.net_if_addrs,
- tolerance_=80 * 1024 if WINDOWS else None)
-
- @unittest.skipIf(TRAVIS, "EPERM on travis")
- def test_net_if_stats(self):
- self.execute(psutil.net_if_stats)
-
- # --- sensors
-
- @skip_if_linux()
- @unittest.skipIf(not HAS_SENSORS_BATTERY, "not supported")
- def test_sensors_battery(self):
- self.execute(psutil.sensors_battery)
-
- @skip_if_linux()
- @unittest.skipIf(not HAS_SENSORS_TEMPERATURES, "not supported")
- def test_sensors_temperatures(self):
- self.execute(psutil.sensors_temperatures)
-
- @skip_if_linux()
- @unittest.skipIf(not HAS_SENSORS_FANS, "not supported")
- def test_sensors_fans(self):
- self.execute(psutil.sensors_fans)
-
- # --- others
-
- @skip_if_linux()
- def test_boot_time(self):
- self.execute(psutil.boot_time)
-
- # XXX - on Windows this produces a false positive
- @unittest.skipIf(WINDOWS, "XXX produces a false positive on Windows")
- def test_users(self):
- self.execute(psutil.users)
-
- if WINDOWS:
-
- # --- win services
-
- def test_win_service_iter(self):
- self.execute(cext.winservice_enumerate)
-
- def test_win_service_get(self):
- pass
-
- def test_win_service_get_config(self):
- name = next(psutil.win_service_iter()).name()
- self.execute(cext.winservice_query_config, name)
-
- def test_win_service_get_status(self):
- name = next(psutil.win_service_iter()).name()
- self.execute(cext.winservice_query_status, name)
-
- def test_win_service_get_description(self):
- name = next(psutil.win_service_iter()).name()
- self.execute(cext.winservice_query_descr, name)
-
-
-if __name__ == '__main__':
- run_test_module_by_name(__file__)
diff --git a/server/www/packages/packages-darwin/x64/psutil/tests/test_misc.py b/server/www/packages/packages-darwin/x64/psutil/tests/test_misc.py
deleted file mode 100644
index 1d9067e..0000000
--- a/server/www/packages/packages-darwin/x64/psutil/tests/test_misc.py
+++ /dev/null
@@ -1,1046 +0,0 @@
-#!/usr/bin/env python
-# -*- 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 contextlib
-import errno
-import json
-import os
-import pickle
-import socket
-import stat
-
-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 bind_socket
-from psutil.tests import bind_unix_socket
-from psutil.tests import call_until
-from psutil.tests import chdir
-from psutil.tests import create_proc_children_pair
-from psutil.tests import create_sockets
-from psutil.tests import create_zombie_proc
-from psutil.tests import DEVNULL
-from psutil.tests import get_free_port
-from psutil.tests import get_test_subprocess
-from psutil.tests import HAS_BATTERY
-from psutil.tests import HAS_CONNECTIONS_UNIX
-from psutil.tests import HAS_MEMORY_FULL_INFO
-from psutil.tests import HAS_MEMORY_MAPS
-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 is_namedtuple
-from psutil.tests import mock
-from psutil.tests import PYTHON_EXE
-from psutil.tests import reap_children
-from psutil.tests import reload_module
-from psutil.tests import retry
-from psutil.tests import ROOT_DIR
-from psutil.tests import run_test_module_by_name
-from psutil.tests import safe_mkdir
-from psutil.tests import safe_rmpath
-from psutil.tests import SCRIPTS_DIR
-from psutil.tests import sh
-from psutil.tests import tcp_socketpair
-from psutil.tests import TESTFN
-from psutil.tests import TOX
-from psutil.tests import TRAVIS
-from psutil.tests import unittest
-from psutil.tests import unix_socket_path
-from psutil.tests import unix_socketpair
-from psutil.tests import wait_for_file
-from psutil.tests import wait_for_pid
-import psutil
-import psutil.tests
-
-
-# ===================================================================
-# --- Misc / generic tests.
-# ===================================================================
-
-
-class TestMisc(unittest.TestCase):
-
- def test_process__repr__(self, func=repr):
- p = psutil.Process()
- r = func(p)
- self.assertIn("psutil.Process", r)
- self.assertIn("pid=%s" % p.pid, r)
- self.assertIn("name=", r)
- self.assertIn(p.name(), 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("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 ('callable', 'error', 'namedtuple', 'tests',
- 'long', 'test', 'NUM_CPUS', 'BOOT_TIME',
- 'TOTAL_PHYMEM'):
- 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.foo()
- f.foo()
- self.assertEqual(len(calls), 1)
-
- # deactivate
- calls = []
- f.foo.cache_deactivate()
- 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)
- sock.bind(("::1", 0))
-
- 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.EINVAL, "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 TRAVIS 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(unittest.TestCase):
-
- 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 psutil.disk_io_counters() or not psutil.net_io_counters(),
- "no disks or NICs available")
- def test_cache_clear_public_apis(self):
- 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(TOX, "can't test on TOX")
-# See: https://travis-ci.org/giampaolo/psutil/jobs/295224806
-@unittest.skipIf(TRAVIS and not os.path.exists(SCRIPTS_DIR),
- "can't locate scripts directory")
-class TestScripts(unittest.TestCase):
- """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()))
-
- # can't find users on APPVEYOR or TRAVIS
- @unittest.skipIf(APPVEYOR or TRAVIS and not psutil.users(),
- "unreliable on APPVEYOR or TRAVIS")
- 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')
-
- # permission denied on travis
- @unittest.skipIf(TRAVIS, "unreliable on TRAVIS")
- 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()))
-
- @unittest.skipIf(not HAS_MEMORY_FULL_INFO, "not supported")
- def test_procsmem(self):
- self.assert_stdout('procsmem.py', stderr=DEVNULL)
-
- 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")
- @unittest.skipIf(TRAVIS, "unreliable on TRAVIS")
- def test_temperatures(self):
- self.assert_stdout('temperatures.py')
-
- @unittest.skipIf(not HAS_SENSORS_FANS, "not supported")
- @unittest.skipIf(TRAVIS, "unreliable on TRAVIS")
- def test_fans(self):
- 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')
-
- def test_sensors(self):
- self.assert_stdout('sensors.py')
-
-
-# ===================================================================
-# --- Unit tests for test utilities.
-# ===================================================================
-
-
-class TestRetryDecorator(unittest.TestCase):
-
- @mock.patch('time.sleep')
- def test_retry_success(self, sleep):
- # Fail 3 times out of 5; make sure the decorated fun returns.
-
- @retry(retries=5, interval=1, logfun=None)
- def foo():
- while queue:
- queue.pop()
- 1 / 0
- return 1
-
- queue = list(range(3))
- self.assertEqual(foo(), 1)
- self.assertEqual(sleep.call_count, 3)
-
- @mock.patch('time.sleep')
- def test_retry_failure(self, sleep):
- # Fail 6 times out of 5; th function is supposed to raise exc.
-
- @retry(retries=5, interval=1, logfun=None)
- def foo():
- while queue:
- queue.pop()
- 1 / 0
- return 1
-
- queue = list(range(6))
- self.assertRaises(ZeroDivisionError, foo)
- self.assertEqual(sleep.call_count, 5)
-
- @mock.patch('time.sleep')
- def test_exception_arg(self, sleep):
- @retry(exception=ValueError, interval=1)
- def foo():
- raise TypeError
-
- self.assertRaises(TypeError, foo)
- self.assertEqual(sleep.call_count, 0)
-
- @mock.patch('time.sleep')
- def test_no_interval_arg(self, sleep):
- # if interval is not specified sleep is not supposed to be called
-
- @retry(retries=5, interval=None, logfun=None)
- def foo():
- 1 / 0
-
- self.assertRaises(ZeroDivisionError, foo)
- self.assertEqual(sleep.call_count, 0)
-
- @mock.patch('time.sleep')
- def test_retries_arg(self, sleep):
-
- @retry(retries=5, interval=1, logfun=None)
- def foo():
- 1 / 0
-
- self.assertRaises(ZeroDivisionError, foo)
- self.assertEqual(sleep.call_count, 5)
-
- @mock.patch('time.sleep')
- def test_retries_and_timeout_args(self, sleep):
- self.assertRaises(ValueError, retry, retries=5, timeout=1)
-
-
-class TestSyncTestUtils(unittest.TestCase):
-
- def tearDown(self):
- safe_rmpath(TESTFN)
-
- def test_wait_for_pid(self):
- wait_for_pid(os.getpid())
- nopid = max(psutil.pids()) + 99999
- with mock.patch('psutil.tests.retry.__iter__', return_value=iter([0])):
- self.assertRaises(psutil.NoSuchProcess, wait_for_pid, nopid)
-
- def test_wait_for_file(self):
- with open(TESTFN, 'w') as f:
- f.write('foo')
- wait_for_file(TESTFN)
- assert not os.path.exists(TESTFN)
-
- def test_wait_for_file_empty(self):
- with open(TESTFN, 'w'):
- pass
- wait_for_file(TESTFN, empty=True)
- assert not os.path.exists(TESTFN)
-
- def test_wait_for_file_no_file(self):
- with mock.patch('psutil.tests.retry.__iter__', return_value=iter([0])):
- self.assertRaises(IOError, wait_for_file, TESTFN)
-
- def test_wait_for_file_no_delete(self):
- with open(TESTFN, 'w') as f:
- f.write('foo')
- wait_for_file(TESTFN, delete=False)
- assert os.path.exists(TESTFN)
-
- def test_call_until(self):
- ret = call_until(lambda: 1, "ret == 1")
- self.assertEqual(ret, 1)
-
-
-class TestFSTestUtils(unittest.TestCase):
-
- def setUp(self):
- safe_rmpath(TESTFN)
-
- tearDown = setUp
-
- def test_safe_mkdir(self):
- safe_mkdir(TESTFN)
- assert os.path.isdir(TESTFN)
- safe_mkdir(TESTFN)
- assert os.path.isdir(TESTFN)
-
- def test_safe_rmpath(self):
- # test file is removed
- open(TESTFN, 'w').close()
- safe_rmpath(TESTFN)
- assert not os.path.exists(TESTFN)
- # test no exception if path does not exist
- safe_rmpath(TESTFN)
- # test dir is removed
- os.mkdir(TESTFN)
- safe_rmpath(TESTFN)
- assert not os.path.exists(TESTFN)
- # test other exceptions are raised
- with mock.patch('psutil.tests.os.stat',
- side_effect=OSError(errno.EINVAL, "")) as m:
- with self.assertRaises(OSError):
- safe_rmpath(TESTFN)
- assert m.called
-
- def test_chdir(self):
- base = os.getcwd()
- os.mkdir(TESTFN)
- with chdir(TESTFN):
- self.assertEqual(os.getcwd(), os.path.join(base, TESTFN))
- self.assertEqual(os.getcwd(), base)
-
-
-class TestProcessUtils(unittest.TestCase):
-
- def test_reap_children(self):
- subp = get_test_subprocess()
- p = psutil.Process(subp.pid)
- assert p.is_running()
- reap_children()
- assert not p.is_running()
- assert not psutil.tests._pids_started
- assert not psutil.tests._subprocesses_started
-
- def test_create_proc_children_pair(self):
- p1, p2 = create_proc_children_pair()
- self.assertNotEqual(p1.pid, p2.pid)
- assert p1.is_running()
- assert p2.is_running()
- children = psutil.Process().children(recursive=True)
- self.assertEqual(len(children), 2)
- self.assertIn(p1, children)
- self.assertIn(p2, children)
- self.assertEqual(p1.ppid(), os.getpid())
- self.assertEqual(p2.ppid(), p1.pid)
-
- # make sure both of them are cleaned up
- reap_children()
- assert not p1.is_running()
- assert not p2.is_running()
- assert not psutil.tests._pids_started
- assert not psutil.tests._subprocesses_started
-
- @unittest.skipIf(not POSIX, "POSIX only")
- def test_create_zombie_proc(self):
- zpid = create_zombie_proc()
- self.addCleanup(reap_children, recursive=True)
- p = psutil.Process(zpid)
- self.assertEqual(p.status(), psutil.STATUS_ZOMBIE)
-
-
-class TestNetUtils(unittest.TestCase):
-
- def bind_socket(self):
- port = get_free_port()
- with contextlib.closing(bind_socket(addr=('', port))) as s:
- self.assertEqual(s.getsockname()[1], port)
-
- @unittest.skipIf(not POSIX, "POSIX only")
- def test_bind_unix_socket(self):
- with unix_socket_path() as name:
- sock = bind_unix_socket(name)
- with contextlib.closing(sock):
- self.assertEqual(sock.family, socket.AF_UNIX)
- self.assertEqual(sock.type, socket.SOCK_STREAM)
- self.assertEqual(sock.getsockname(), name)
- assert os.path.exists(name)
- assert stat.S_ISSOCK(os.stat(name).st_mode)
- # UDP
- with unix_socket_path() as name:
- sock = bind_unix_socket(name, type=socket.SOCK_DGRAM)
- with contextlib.closing(sock):
- self.assertEqual(sock.type, socket.SOCK_DGRAM)
-
- def tcp_tcp_socketpair(self):
- addr = ("127.0.0.1", get_free_port())
- server, client = tcp_socketpair(socket.AF_INET, addr=addr)
- with contextlib.closing(server):
- with contextlib.closing(client):
- # Ensure they are connected and the positions are
- # correct.
- self.assertEqual(server.getsockname(), addr)
- self.assertEqual(client.getpeername(), addr)
- self.assertNotEqual(client.getsockname(), addr)
-
- @unittest.skipIf(not POSIX, "POSIX only")
- def test_unix_socketpair(self):
- p = psutil.Process()
- num_fds = p.num_fds()
- assert not p.connections(kind='unix')
- with unix_socket_path() as name:
- server, client = unix_socketpair(name)
- try:
- assert os.path.exists(name)
- assert stat.S_ISSOCK(os.stat(name).st_mode)
- self.assertEqual(p.num_fds() - num_fds, 2)
- self.assertEqual(len(p.connections(kind='unix')), 2)
- self.assertEqual(server.getsockname(), name)
- self.assertEqual(client.getpeername(), name)
- finally:
- client.close()
- server.close()
-
- def test_create_sockets(self):
- with create_sockets() as socks:
- fams = collections.defaultdict(int)
- types = collections.defaultdict(int)
- for s in socks:
- fams[s.family] += 1
- # work around http://bugs.python.org/issue30204
- types[s.getsockopt(socket.SOL_SOCKET, socket.SO_TYPE)] += 1
- self.assertGreaterEqual(fams[socket.AF_INET], 2)
- if supports_ipv6():
- self.assertGreaterEqual(fams[socket.AF_INET6], 2)
- if POSIX and HAS_CONNECTIONS_UNIX:
- self.assertGreaterEqual(fams[socket.AF_UNIX], 2)
- self.assertGreaterEqual(types[socket.SOCK_STREAM], 2)
- self.assertGreaterEqual(types[socket.SOCK_DGRAM], 2)
-
-
-class TestOtherUtils(unittest.TestCase):
-
- def test_is_namedtuple(self):
- assert is_namedtuple(collections.namedtuple('foo', 'a b c')(1, 2, 3))
- assert not is_namedtuple(tuple())
-
-
-if __name__ == '__main__':
- run_test_module_by_name(__file__)
diff --git a/server/www/packages/packages-darwin/x64/psutil/tests/test_osx.py b/server/www/packages/packages-darwin/x64/psutil/tests/test_osx.py
deleted file mode 100644
index 557af9f..0000000
--- a/server/www/packages/packages-darwin/x64/psutil/tests/test_osx.py
+++ /dev/null
@@ -1,303 +0,0 @@
-#!/usr/bin/env python
-
-# 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.
-
-"""MACOS specific tests."""
-
-import os
-import re
-import time
-
-import psutil
-from psutil import MACOS
-from psutil.tests import create_zombie_proc
-from psutil.tests import get_test_subprocess
-from psutil.tests import HAS_BATTERY
-from psutil.tests import MEMORY_TOLERANCE
-from psutil.tests import reap_children
-from psutil.tests import retry_before_failing
-from psutil.tests import run_test_module_by_name
-from psutil.tests import sh
-from psutil.tests import unittest
-
-
-PAGESIZE = os.sysconf("SC_PAGE_SIZE") if MACOS else None
-
-
-def sysctl(cmdline):
- """Expects a sysctl command with an argument and parse the result
- returning only the value of interest.
- """
- out = sh(cmdline)
- result = out.split()[1]
- try:
- return int(result)
- except ValueError:
- return result
-
-
-def vm_stat(field):
- """Wrapper around 'vm_stat' cmdline utility."""
- out = sh('vm_stat')
- for line in out.split('\n'):
- if field in line:
- break
- else:
- raise ValueError("line not found")
- return int(re.search(r'\d+', line).group(0)) * PAGESIZE
-
-
-# http://code.activestate.com/recipes/578019/
-def human2bytes(s):
- SYMBOLS = {
- 'customary': ('B', 'K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y'),
- }
- init = s
- num = ""
- while s and s[0:1].isdigit() or s[0:1] == '.':
- num += s[0]
- s = s[1:]
- num = float(num)
- letter = s.strip()
- for name, sset in SYMBOLS.items():
- if letter in sset:
- break
- else:
- if letter == 'k':
- sset = SYMBOLS['customary']
- letter = letter.upper()
- else:
- raise ValueError("can't interpret %r" % init)
- prefix = {sset[0]: 1}
- for i, s in enumerate(sset[1:]):
- prefix[s] = 1 << (i + 1) * 10
- return int(num * prefix[letter])
-
-
-@unittest.skipIf(not MACOS, "MACOS only")
-class TestProcess(unittest.TestCase):
-
- @classmethod
- def setUpClass(cls):
- cls.pid = get_test_subprocess().pid
-
- @classmethod
- def tearDownClass(cls):
- reap_children()
-
- def test_process_create_time(self):
- output = sh("ps -o lstart -p %s" % self.pid)
- start_ps = output.replace('STARTED', '').strip()
- hhmmss = start_ps.split(' ')[-2]
- year = start_ps.split(' ')[-1]
- start_psutil = psutil.Process(self.pid).create_time()
- self.assertEqual(
- hhmmss,
- time.strftime("%H:%M:%S", time.localtime(start_psutil)))
- self.assertEqual(
- year,
- time.strftime("%Y", time.localtime(start_psutil)))
-
-
-@unittest.skipIf(not MACOS, "MACOS only")
-class TestZombieProcessAPIs(unittest.TestCase):
-
- @classmethod
- def setUpClass(cls):
- zpid = create_zombie_proc()
- cls.p = psutil.Process(zpid)
-
- @classmethod
- def tearDownClass(cls):
- reap_children(recursive=True)
-
- def test_pidtask_info(self):
- self.assertEqual(self.p.status(), psutil.STATUS_ZOMBIE)
- self.p.ppid()
- self.p.uids()
- self.p.gids()
- self.p.terminal()
- self.p.create_time()
-
- def test_exe(self):
- self.assertRaises(psutil.ZombieProcess, self.p.exe)
-
- def test_cmdline(self):
- self.assertRaises(psutil.ZombieProcess, self.p.cmdline)
-
- def test_environ(self):
- self.assertRaises(psutil.ZombieProcess, self.p.environ)
-
- def test_cwd(self):
- self.assertRaises(psutil.ZombieProcess, self.p.cwd)
-
- def test_memory_full_info(self):
- self.assertRaises(psutil.ZombieProcess, self.p.memory_full_info)
-
- def test_cpu_times(self):
- self.assertRaises(psutil.ZombieProcess, self.p.cpu_times)
-
- def test_num_ctx_switches(self):
- self.assertRaises(psutil.ZombieProcess, self.p.num_ctx_switches)
-
- def test_num_threads(self):
- self.assertRaises(psutil.ZombieProcess, self.p.num_threads)
-
- def test_open_files(self):
- self.assertRaises(psutil.ZombieProcess, self.p.open_files)
-
- def test_connections(self):
- self.assertRaises(psutil.ZombieProcess, self.p.connections)
-
- def test_num_fds(self):
- self.assertRaises(psutil.ZombieProcess, self.p.num_fds)
-
- def test_threads(self):
- self.assertRaises((psutil.ZombieProcess, psutil.AccessDenied),
- self.p.threads)
-
- def test_memory_maps(self):
- self.assertRaises(psutil.ZombieProcess, self.p.memory_maps)
-
-
-@unittest.skipIf(not MACOS, "MACOS only")
-class TestSystemAPIs(unittest.TestCase):
-
- # --- disk
-
- def test_disks(self):
- # test psutil.disk_usage() and psutil.disk_partitions()
- # against "df -a"
- def df(path):
- out = sh('df -k "%s"' % path).strip()
- lines = out.split('\n')
- lines.pop(0)
- line = lines.pop(0)
- dev, total, used, free = line.split()[:4]
- if dev == 'none':
- dev = ''
- total = int(total) * 1024
- used = int(used) * 1024
- free = int(free) * 1024
- return dev, total, used, free
-
- for part in psutil.disk_partitions(all=False):
- usage = psutil.disk_usage(part.mountpoint)
- dev, total, used, free = df(part.mountpoint)
- self.assertEqual(part.device, dev)
- self.assertEqual(usage.total, total)
- # 10 MB tollerance
- if abs(usage.free - free) > 10 * 1024 * 1024:
- self.fail("psutil=%s, df=%s" % usage.free, free)
- if abs(usage.used - used) > 10 * 1024 * 1024:
- self.fail("psutil=%s, df=%s" % usage.used, used)
-
- # --- cpu
-
- def test_cpu_count_logical(self):
- num = sysctl("sysctl hw.logicalcpu")
- self.assertEqual(num, psutil.cpu_count(logical=True))
-
- def test_cpu_count_physical(self):
- num = sysctl("sysctl hw.physicalcpu")
- self.assertEqual(num, psutil.cpu_count(logical=False))
-
- def test_cpu_freq(self):
- freq = psutil.cpu_freq()
- self.assertEqual(
- freq.current * 1000 * 1000, sysctl("sysctl hw.cpufrequency"))
- self.assertEqual(
- freq.min * 1000 * 1000, sysctl("sysctl hw.cpufrequency_min"))
- self.assertEqual(
- freq.max * 1000 * 1000, sysctl("sysctl hw.cpufrequency_max"))
-
- # --- virtual mem
-
- def test_vmem_total(self):
- sysctl_hwphymem = sysctl('sysctl hw.memsize')
- self.assertEqual(sysctl_hwphymem, psutil.virtual_memory().total)
-
- @retry_before_failing()
- def test_vmem_free(self):
- vmstat_val = vm_stat("free")
- psutil_val = psutil.virtual_memory().free
- self.assertAlmostEqual(psutil_val, vmstat_val, delta=MEMORY_TOLERANCE)
-
- @retry_before_failing()
- def test_vmem_available(self):
- vmstat_val = vm_stat("inactive") + vm_stat("free")
- psutil_val = psutil.virtual_memory().available
- self.assertAlmostEqual(psutil_val, vmstat_val, delta=MEMORY_TOLERANCE)
-
- @retry_before_failing()
- def test_vmem_active(self):
- vmstat_val = vm_stat("active")
- psutil_val = psutil.virtual_memory().active
- self.assertAlmostEqual(psutil_val, vmstat_val, delta=MEMORY_TOLERANCE)
-
- @retry_before_failing()
- def test_vmem_inactive(self):
- vmstat_val = vm_stat("inactive")
- psutil_val = psutil.virtual_memory().inactive
- self.assertAlmostEqual(psutil_val, vmstat_val, delta=MEMORY_TOLERANCE)
-
- @retry_before_failing()
- def test_vmem_wired(self):
- vmstat_val = vm_stat("wired")
- psutil_val = psutil.virtual_memory().wired
- self.assertAlmostEqual(psutil_val, vmstat_val, delta=MEMORY_TOLERANCE)
-
- # --- swap mem
-
- @retry_before_failing()
- def test_swapmem_sin(self):
- vmstat_val = vm_stat("Pageins")
- psutil_val = psutil.swap_memory().sin
- self.assertEqual(psutil_val, vmstat_val)
-
- @retry_before_failing()
- def test_swapmem_sout(self):
- vmstat_val = vm_stat("Pageout")
- psutil_val = psutil.swap_memory().sout
- self.assertEqual(psutil_val, vmstat_val)
-
- # Not very reliable.
- # def test_swapmem_total(self):
- # out = sh('sysctl vm.swapusage')
- # out = out.replace('vm.swapusage: ', '')
- # total, used, free = re.findall('\d+.\d+\w', out)
- # psutil_smem = psutil.swap_memory()
- # self.assertEqual(psutil_smem.total, human2bytes(total))
- # self.assertEqual(psutil_smem.used, human2bytes(used))
- # self.assertEqual(psutil_smem.free, human2bytes(free))
-
- # --- network
-
- def test_net_if_stats(self):
- for name, stats in psutil.net_if_stats().items():
- try:
- out = sh("ifconfig %s" % name)
- except RuntimeError:
- pass
- else:
- self.assertEqual(stats.isup, 'RUNNING' in out, msg=out)
- self.assertEqual(stats.mtu,
- int(re.findall(r'mtu (\d+)', out)[0]))
-
- # --- sensors_battery
-
- @unittest.skipIf(not HAS_BATTERY, "no battery")
- def test_sensors_battery(self):
- out = sh("pmset -g batt")
- percent = re.search("(\d+)%", out).group(1)
- drawing_from = re.search("Now drawing from '([^']+)'", out).group(1)
- power_plugged = drawing_from == "AC Power"
- psutil_result = psutil.sensors_battery()
- self.assertEqual(psutil_result.power_plugged, power_plugged)
- self.assertEqual(psutil_result.percent, int(percent))
-
-
-if __name__ == '__main__':
- run_test_module_by_name(__file__)
diff --git a/server/www/packages/packages-darwin/x64/psutil/tests/test_posix.py b/server/www/packages/packages-darwin/x64/psutil/tests/test_posix.py
deleted file mode 100644
index b80128c..0000000
--- a/server/www/packages/packages-darwin/x64/psutil/tests/test_posix.py
+++ /dev/null
@@ -1,418 +0,0 @@
-#!/usr/bin/env python
-# -*- 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.
-
-"""POSIX specific tests."""
-
-import datetime
-import errno
-import os
-import re
-import subprocess
-import sys
-import time
-
-import psutil
-from psutil import AIX
-from psutil import BSD
-from psutil import LINUX
-from psutil import MACOS
-from psutil import OPENBSD
-from psutil import POSIX
-from psutil import SUNOS
-from psutil._compat import PY3
-from psutil.tests import APPVEYOR
-from psutil.tests import get_kernel_version
-from psutil.tests import get_test_subprocess
-from psutil.tests import mock
-from psutil.tests import PYTHON_EXE
-from psutil.tests import reap_children
-from psutil.tests import retry_before_failing
-from psutil.tests import run_test_module_by_name
-from psutil.tests import sh
-from psutil.tests import skip_on_access_denied
-from psutil.tests import TRAVIS
-from psutil.tests import unittest
-from psutil.tests import wait_for_pid
-from psutil.tests import which
-
-
-def ps(cmd):
- """Expects a ps command with a -o argument and parse the result
- returning only the value of interest.
- """
- if not LINUX:
- cmd = cmd.replace(" --no-headers ", " ")
- if SUNOS:
- cmd = cmd.replace("-o start", "-o stime")
- if AIX:
- cmd = cmd.replace("-o rss", "-o rssize")
- output = sh(cmd)
- if not LINUX:
- output = output.split('\n')[1].strip()
- try:
- return int(output)
- except ValueError:
- return output
-
-# ps "-o" field names differ wildly between platforms.
-# "comm" means "only executable name" but is not available on BSD platforms.
-# "args" means "command with all its arguments", and is also not available
-# on BSD platforms.
-# "command" is like "args" on most platforms, but like "comm" on AIX,
-# and not available on SUNOS.
-# so for the executable name we can use "comm" on Solaris and split "command"
-# on other platforms.
-# to get the cmdline (with args) we have to use "args" on AIX and
-# Solaris, and can use "command" on all others.
-
-
-def ps_name(pid):
- field = "command"
- if SUNOS:
- field = "comm"
- return ps("ps --no-headers -o %s -p %s" % (field, pid)).split(' ')[0]
-
-
-def ps_args(pid):
- field = "command"
- if AIX or SUNOS:
- field = "args"
- return ps("ps --no-headers -o %s -p %s" % (field, pid))
-
-
-@unittest.skipIf(not POSIX, "POSIX only")
-class TestProcess(unittest.TestCase):
- """Compare psutil results against 'ps' command line utility (mainly)."""
-
- @classmethod
- def setUpClass(cls):
- cls.pid = get_test_subprocess([PYTHON_EXE, "-E", "-O"],
- stdin=subprocess.PIPE).pid
- wait_for_pid(cls.pid)
-
- @classmethod
- def tearDownClass(cls):
- reap_children()
-
- def test_ppid(self):
- ppid_ps = ps("ps --no-headers -o ppid -p %s" % self.pid)
- ppid_psutil = psutil.Process(self.pid).ppid()
- self.assertEqual(ppid_ps, ppid_psutil)
-
- def test_uid(self):
- uid_ps = ps("ps --no-headers -o uid -p %s" % self.pid)
- uid_psutil = psutil.Process(self.pid).uids().real
- self.assertEqual(uid_ps, uid_psutil)
-
- def test_gid(self):
- gid_ps = ps("ps --no-headers -o rgid -p %s" % self.pid)
- gid_psutil = psutil.Process(self.pid).gids().real
- self.assertEqual(gid_ps, gid_psutil)
-
- def test_username(self):
- username_ps = ps("ps --no-headers -o user -p %s" % self.pid)
- username_psutil = psutil.Process(self.pid).username()
- self.assertEqual(username_ps, username_psutil)
-
- def test_username_no_resolution(self):
- # Emulate a case where the system can't resolve the uid to
- # a username in which case psutil is supposed to return
- # the stringified uid.
- p = psutil.Process()
- with mock.patch("psutil.pwd.getpwuid", side_effect=KeyError) as fun:
- self.assertEqual(p.username(), str(p.uids().real))
- assert fun.called
-
- @skip_on_access_denied()
- @retry_before_failing()
- def test_rss_memory(self):
- # give python interpreter some time to properly initialize
- # so that the results are the same
- time.sleep(0.1)
- rss_ps = ps("ps --no-headers -o rss -p %s" % self.pid)
- rss_psutil = psutil.Process(self.pid).memory_info()[0] / 1024
- self.assertEqual(rss_ps, rss_psutil)
-
- @skip_on_access_denied()
- @retry_before_failing()
- def test_vsz_memory(self):
- # give python interpreter some time to properly initialize
- # so that the results are the same
- time.sleep(0.1)
- vsz_ps = ps("ps --no-headers -o vsz -p %s" % self.pid)
- vsz_psutil = psutil.Process(self.pid).memory_info()[1] / 1024
- self.assertEqual(vsz_ps, vsz_psutil)
-
- def test_name(self):
- name_ps = ps_name(self.pid)
- # remove path if there is any, from the command
- name_ps = os.path.basename(name_ps).lower()
- name_psutil = psutil.Process(self.pid).name().lower()
- # ...because of how we calculate PYTHON_EXE; on MACOS this may
- # be "pythonX.Y".
- name_ps = re.sub(r"\d.\d", "", name_ps)
- name_psutil = re.sub(r"\d.\d", "", name_psutil)
- self.assertEqual(name_ps, name_psutil)
-
- def test_name_long(self):
- # On UNIX the kernel truncates the name to the first 15
- # characters. In such a case psutil tries to determine the
- # full name from the cmdline.
- name = "long-program-name"
- cmdline = ["long-program-name-extended", "foo", "bar"]
- with mock.patch("psutil._psplatform.Process.name",
- return_value=name):
- with mock.patch("psutil._psplatform.Process.cmdline",
- return_value=cmdline):
- p = psutil.Process()
- self.assertEqual(p.name(), "long-program-name-extended")
-
- def test_name_long_cmdline_ad_exc(self):
- # Same as above but emulates a case where cmdline() raises
- # AccessDenied in which case psutil is supposed to return
- # the truncated name instead of crashing.
- name = "long-program-name"
- with mock.patch("psutil._psplatform.Process.name",
- return_value=name):
- with mock.patch("psutil._psplatform.Process.cmdline",
- side_effect=psutil.AccessDenied(0, "")):
- p = psutil.Process()
- self.assertEqual(p.name(), "long-program-name")
-
- def test_name_long_cmdline_nsp_exc(self):
- # Same as above but emulates a case where cmdline() raises NSP
- # which is supposed to propagate.
- name = "long-program-name"
- with mock.patch("psutil._psplatform.Process.name",
- return_value=name):
- with mock.patch("psutil._psplatform.Process.cmdline",
- side_effect=psutil.NoSuchProcess(0, "")):
- p = psutil.Process()
- self.assertRaises(psutil.NoSuchProcess, p.name)
-
- @unittest.skipIf(MACOS or BSD, 'ps -o start not available')
- def test_create_time(self):
- time_ps = ps("ps --no-headers -o start -p %s" % self.pid).split(' ')[0]
- time_psutil = psutil.Process(self.pid).create_time()
- time_psutil_tstamp = datetime.datetime.fromtimestamp(
- time_psutil).strftime("%H:%M:%S")
- # sometimes ps shows the time rounded up instead of down, so we check
- # for both possible values
- round_time_psutil = round(time_psutil)
- round_time_psutil_tstamp = datetime.datetime.fromtimestamp(
- round_time_psutil).strftime("%H:%M:%S")
- self.assertIn(time_ps, [time_psutil_tstamp, round_time_psutil_tstamp])
-
- def test_exe(self):
- ps_pathname = ps_name(self.pid)
- psutil_pathname = psutil.Process(self.pid).exe()
- try:
- self.assertEqual(ps_pathname, psutil_pathname)
- except AssertionError:
- # certain platforms such as BSD are more accurate returning:
- # "/usr/local/bin/python2.7"
- # ...instead of:
- # "/usr/local/bin/python"
- # We do not want to consider this difference in accuracy
- # an error.
- adjusted_ps_pathname = ps_pathname[:len(ps_pathname)]
- self.assertEqual(ps_pathname, adjusted_ps_pathname)
-
- def test_cmdline(self):
- ps_cmdline = ps_args(self.pid)
- psutil_cmdline = " ".join(psutil.Process(self.pid).cmdline())
- self.assertEqual(ps_cmdline, psutil_cmdline)
-
- # On SUNOS "ps" reads niceness /proc/pid/psinfo which returns an
- # incorrect value (20); the real deal is getpriority(2) which
- # returns 0; psutil relies on it, see:
- # https://github.com/giampaolo/psutil/issues/1082
- # AIX has the same issue
- @unittest.skipIf(SUNOS, "not reliable on SUNOS")
- @unittest.skipIf(AIX, "not reliable on AIX")
- def test_nice(self):
- ps_nice = ps("ps --no-headers -o nice -p %s" % self.pid)
- psutil_nice = psutil.Process().nice()
- self.assertEqual(ps_nice, psutil_nice)
-
- def test_num_fds(self):
- # Note: this fails from time to time; I'm keen on thinking
- # it doesn't mean something is broken
- def call(p, attr):
- args = ()
- attr = getattr(p, name, None)
- if attr is not None and callable(attr):
- if name == 'rlimit':
- args = (psutil.RLIMIT_NOFILE,)
- attr(*args)
- else:
- attr
-
- p = psutil.Process(os.getpid())
- failures = []
- ignored_names = ['terminate', 'kill', 'suspend', 'resume', 'nice',
- 'send_signal', 'wait', 'children', 'as_dict',
- 'memory_info_ex']
- if LINUX and get_kernel_version() < (2, 6, 36):
- ignored_names.append('rlimit')
- if LINUX and get_kernel_version() < (2, 6, 23):
- ignored_names.append('num_ctx_switches')
- for name in dir(psutil.Process):
- if (name.startswith('_') or name in ignored_names):
- continue
- else:
- try:
- num1 = p.num_fds()
- for x in range(2):
- call(p, name)
- num2 = p.num_fds()
- except psutil.AccessDenied:
- pass
- else:
- if abs(num2 - num1) > 1:
- fail = "failure while processing Process.%s method " \
- "(before=%s, after=%s)" % (name, num1, num2)
- failures.append(fail)
- if failures:
- self.fail('\n' + '\n'.join(failures))
-
-
-@unittest.skipIf(not POSIX, "POSIX only")
-class TestSystemAPIs(unittest.TestCase):
- """Test some system APIs."""
-
- @retry_before_failing()
- def test_pids(self):
- # Note: this test might fail if the OS is starting/killing
- # other processes in the meantime
- if SUNOS or AIX:
- cmd = ["ps", "-A", "-o", "pid"]
- else:
- cmd = ["ps", "ax", "-o", "pid"]
- p = get_test_subprocess(cmd, stdout=subprocess.PIPE)
- output = p.communicate()[0].strip()
- assert p.poll() == 0
- if PY3:
- output = str(output, sys.stdout.encoding)
- pids_ps = []
- for line in output.split('\n')[1:]:
- if line:
- pid = int(line.split()[0].strip())
- pids_ps.append(pid)
- # remove ps subprocess pid which is supposed to be dead in meantime
- pids_ps.remove(p.pid)
- pids_psutil = psutil.pids()
- pids_ps.sort()
- pids_psutil.sort()
-
- # on MACOS and OPENBSD ps doesn't show pid 0
- if MACOS or OPENBSD and 0 not in pids_ps:
- pids_ps.insert(0, 0)
- self.assertEqual(pids_ps, pids_psutil)
-
- # for some reason ifconfig -a does not report all interfaces
- # returned by psutil
- @unittest.skipIf(SUNOS, "unreliable on SUNOS")
- @unittest.skipIf(TRAVIS, "unreliable on TRAVIS")
- @unittest.skipIf(not which('ifconfig'), "no ifconfig cmd")
- def test_nic_names(self):
- output = sh("ifconfig -a")
- for nic in psutil.net_io_counters(pernic=True).keys():
- for line in output.split():
- if line.startswith(nic):
- break
- else:
- self.fail(
- "couldn't find %s nic in 'ifconfig -a' output\n%s" % (
- nic, output))
-
- # can't find users on APPVEYOR or TRAVIS
- @unittest.skipIf(APPVEYOR or TRAVIS and not psutil.users(),
- "unreliable on APPVEYOR or TRAVIS")
- @retry_before_failing()
- def test_users(self):
- out = sh("who")
- lines = out.split('\n')
- users = [x.split()[0] for x in lines]
- terminals = [x.split()[1] for x in lines]
- self.assertEqual(len(users), len(psutil.users()))
- for u in psutil.users():
- self.assertIn(u.name, users)
- self.assertIn(u.terminal, terminals)
-
- def test_pid_exists_let_raise(self):
- # According to "man 2 kill" possible error values for kill
- # are (EINVAL, EPERM, ESRCH). Test that any other errno
- # results in an exception.
- with mock.patch("psutil._psposix.os.kill",
- side_effect=OSError(errno.EBADF, "")) as m:
- self.assertRaises(OSError, psutil._psposix.pid_exists, os.getpid())
- assert m.called
-
- def test_os_waitpid_let_raise(self):
- # os.waitpid() is supposed to catch EINTR and ECHILD only.
- # Test that any other errno results in an exception.
- with mock.patch("psutil._psposix.os.waitpid",
- side_effect=OSError(errno.EBADF, "")) as m:
- self.assertRaises(OSError, psutil._psposix.wait_pid, os.getpid())
- assert m.called
-
- def test_os_waitpid_eintr(self):
- # os.waitpid() is supposed to "retry" on EINTR.
- with mock.patch("psutil._psposix.os.waitpid",
- side_effect=OSError(errno.EINTR, "")) as m:
- self.assertRaises(
- psutil._psposix.TimeoutExpired,
- psutil._psposix.wait_pid, os.getpid(), timeout=0.01)
- assert m.called
-
- def test_os_waitpid_bad_ret_status(self):
- # Simulate os.waitpid() returning a bad status.
- with mock.patch("psutil._psposix.os.waitpid",
- return_value=(1, -1)) as m:
- self.assertRaises(ValueError,
- psutil._psposix.wait_pid, os.getpid())
- assert m.called
-
- # AIX can return '-' in df output instead of numbers, e.g. for /proc
- @unittest.skipIf(AIX, "unreliable on AIX")
- def test_disk_usage(self):
- def df(device):
- out = sh("df -k %s" % device).strip()
- line = out.split('\n')[1]
- fields = line.split()
- total = int(fields[1]) * 1024
- used = int(fields[2]) * 1024
- free = int(fields[3]) * 1024
- percent = float(fields[4].replace('%', ''))
- return (total, used, free, percent)
-
- tolerance = 4 * 1024 * 1024 # 4MB
- for part in psutil.disk_partitions(all=False):
- usage = psutil.disk_usage(part.mountpoint)
- try:
- total, used, free, percent = df(part.device)
- except RuntimeError as err:
- # see:
- # https://travis-ci.org/giampaolo/psutil/jobs/138338464
- # https://travis-ci.org/giampaolo/psutil/jobs/138343361
- err = str(err).lower()
- if "no such file or directory" in err or \
- "raw devices not supported" in err or \
- "permission denied" in err:
- continue
- else:
- raise
- else:
- self.assertAlmostEqual(usage.total, total, delta=tolerance)
- self.assertAlmostEqual(usage.used, used, delta=tolerance)
- self.assertAlmostEqual(usage.free, free, delta=tolerance)
- self.assertAlmostEqual(usage.percent, percent, delta=1)
-
-
-if __name__ == '__main__':
- run_test_module_by_name(__file__)
diff --git a/server/www/packages/packages-darwin/x64/psutil/tests/test_process.py b/server/www/packages/packages-darwin/x64/psutil/tests/test_process.py
deleted file mode 100644
index 2308196..0000000
--- a/server/www/packages/packages-darwin/x64/psutil/tests/test_process.py
+++ /dev/null
@@ -1,1564 +0,0 @@
-#!/usr/bin/env python
-
-# 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.
-
-"""Tests for psutil.Process class."""
-
-import collections
-import errno
-import getpass
-import itertools
-import os
-import signal
-import socket
-import subprocess
-import sys
-import tempfile
-import textwrap
-import time
-import types
-
-import psutil
-
-from psutil import AIX
-from psutil import BSD
-from psutil import LINUX
-from psutil import MACOS
-from psutil import NETBSD
-from psutil import OPENBSD
-from psutil import POSIX
-from psutil import SUNOS
-from psutil import WINDOWS
-from psutil._compat import long
-from psutil._compat import PY3
-from psutil.tests import APPVEYOR
-from psutil.tests import call_until
-from psutil.tests import copyload_shared_lib
-from psutil.tests import create_exe
-from psutil.tests import create_proc_children_pair
-from psutil.tests import create_zombie_proc
-from psutil.tests import enum
-from psutil.tests import get_test_subprocess
-from psutil.tests import get_winver
-from psutil.tests import HAS_CPU_AFFINITY
-from psutil.tests import HAS_ENVIRON
-from psutil.tests import HAS_IONICE
-from psutil.tests import HAS_MEMORY_MAPS
-from psutil.tests import HAS_PROC_CPU_NUM
-from psutil.tests import HAS_PROC_IO_COUNTERS
-from psutil.tests import HAS_RLIMIT
-from psutil.tests import HAS_THREADS
-from psutil.tests import mock
-from psutil.tests import PYPY
-from psutil.tests import PYTHON_EXE
-from psutil.tests import reap_children
-from psutil.tests import retry_before_failing
-from psutil.tests import run_test_module_by_name
-from psutil.tests import safe_rmpath
-from psutil.tests import sh
-from psutil.tests import skip_on_access_denied
-from psutil.tests import skip_on_not_implemented
-from psutil.tests import TESTFILE_PREFIX
-from psutil.tests import TESTFN
-from psutil.tests import ThreadTask
-from psutil.tests import TRAVIS
-from psutil.tests import unittest
-from psutil.tests import wait_for_pid
-from psutil.tests import WIN_VISTA
-
-
-# ===================================================================
-# --- psutil.Process class tests
-# ===================================================================
-
-class TestProcess(unittest.TestCase):
- """Tests for psutil.Process class."""
-
- def setUp(self):
- safe_rmpath(TESTFN)
-
- def tearDown(self):
- reap_children()
-
- def test_pid(self):
- p = psutil.Process()
- self.assertEqual(p.pid, os.getpid())
- sproc = get_test_subprocess()
- self.assertEqual(psutil.Process(sproc.pid).pid, sproc.pid)
- with self.assertRaises(AttributeError):
- p.pid = 33
-
- def test_kill(self):
- sproc = get_test_subprocess()
- test_pid = sproc.pid
- p = psutil.Process(test_pid)
- p.kill()
- sig = p.wait()
- self.assertFalse(psutil.pid_exists(test_pid))
- if POSIX:
- self.assertEqual(sig, -signal.SIGKILL)
-
- def test_terminate(self):
- sproc = get_test_subprocess()
- test_pid = sproc.pid
- p = psutil.Process(test_pid)
- p.terminate()
- sig = p.wait()
- self.assertFalse(psutil.pid_exists(test_pid))
- if POSIX:
- self.assertEqual(sig, -signal.SIGTERM)
-
- def test_send_signal(self):
- sig = signal.SIGKILL if POSIX else signal.SIGTERM
- sproc = get_test_subprocess()
- p = psutil.Process(sproc.pid)
- p.send_signal(sig)
- exit_sig = p.wait()
- self.assertFalse(psutil.pid_exists(p.pid))
- if POSIX:
- self.assertEqual(exit_sig, -sig)
- #
- sproc = get_test_subprocess()
- p = psutil.Process(sproc.pid)
- p.send_signal(sig)
- with mock.patch('psutil.os.kill',
- side_effect=OSError(errno.ESRCH, "")):
- with self.assertRaises(psutil.NoSuchProcess):
- p.send_signal(sig)
- #
- sproc = get_test_subprocess()
- p = psutil.Process(sproc.pid)
- p.send_signal(sig)
- with mock.patch('psutil.os.kill',
- side_effect=OSError(errno.EPERM, "")):
- with self.assertRaises(psutil.AccessDenied):
- psutil.Process().send_signal(sig)
- # Sending a signal to process with PID 0 is not allowed as
- # it would affect every process in the process group of
- # the calling process (os.getpid()) instead of PID 0").
- if 0 in psutil.pids():
- p = psutil.Process(0)
- self.assertRaises(ValueError, p.send_signal, signal.SIGTERM)
-
- def test_wait(self):
- # check exit code signal
- sproc = get_test_subprocess()
- p = psutil.Process(sproc.pid)
- p.kill()
- code = p.wait()
- if POSIX:
- self.assertEqual(code, -signal.SIGKILL)
- else:
- self.assertEqual(code, signal.SIGTERM)
- self.assertFalse(p.is_running())
-
- sproc = get_test_subprocess()
- p = psutil.Process(sproc.pid)
- p.terminate()
- code = p.wait()
- if POSIX:
- self.assertEqual(code, -signal.SIGTERM)
- else:
- self.assertEqual(code, signal.SIGTERM)
- self.assertFalse(p.is_running())
-
- # check sys.exit() code
- code = "import time, sys; time.sleep(0.01); sys.exit(5);"
- sproc = get_test_subprocess([PYTHON_EXE, "-c", code])
- p = psutil.Process(sproc.pid)
- self.assertEqual(p.wait(), 5)
- self.assertFalse(p.is_running())
-
- # Test wait() issued twice.
- # It is not supposed to raise NSP when the process is gone.
- # On UNIX this should return None, on Windows it should keep
- # returning the exit code.
- sproc = get_test_subprocess([PYTHON_EXE, "-c", code])
- p = psutil.Process(sproc.pid)
- self.assertEqual(p.wait(), 5)
- self.assertIn(p.wait(), (5, None))
-
- # test timeout
- sproc = get_test_subprocess()
- p = psutil.Process(sproc.pid)
- p.name()
- self.assertRaises(psutil.TimeoutExpired, p.wait, 0.01)
-
- # timeout < 0 not allowed
- self.assertRaises(ValueError, p.wait, -1)
-
- def test_wait_non_children(self):
- # Test wait() against a process which is not our direct
- # child.
- p1, p2 = create_proc_children_pair()
- self.assertRaises(psutil.TimeoutExpired, p1.wait, 0.01)
- self.assertRaises(psutil.TimeoutExpired, p2.wait, 0.01)
- # We also terminate the direct child otherwise the
- # grandchild will hang until the parent is gone.
- p1.terminate()
- p2.terminate()
- ret1 = p1.wait()
- ret2 = p2.wait()
- if POSIX:
- self.assertEqual(ret1, -signal.SIGTERM)
- # For processes which are not our children we're supposed
- # to get None.
- self.assertEqual(ret2, None)
- else:
- self.assertEqual(ret1, signal.SIGTERM)
- self.assertEqual(ret1, signal.SIGTERM)
-
- def test_wait_timeout_0(self):
- sproc = get_test_subprocess()
- p = psutil.Process(sproc.pid)
- self.assertRaises(psutil.TimeoutExpired, p.wait, 0)
- p.kill()
- stop_at = time.time() + 2
- while True:
- try:
- code = p.wait(0)
- except psutil.TimeoutExpired:
- if time.time() >= stop_at:
- raise
- else:
- break
- if POSIX:
- self.assertEqual(code, -signal.SIGKILL)
- else:
- self.assertEqual(code, signal.SIGTERM)
- self.assertFalse(p.is_running())
-
- def test_cpu_percent(self):
- p = psutil.Process()
- p.cpu_percent(interval=0.001)
- p.cpu_percent(interval=0.001)
- for x in range(100):
- percent = p.cpu_percent(interval=None)
- self.assertIsInstance(percent, float)
- self.assertGreaterEqual(percent, 0.0)
- with self.assertRaises(ValueError):
- p.cpu_percent(interval=-1)
-
- def test_cpu_percent_numcpus_none(self):
- # See: https://github.com/giampaolo/psutil/issues/1087
- with mock.patch('psutil.cpu_count', return_value=None) as m:
- psutil.Process().cpu_percent()
- assert m.called
-
- def test_cpu_times(self):
- times = psutil.Process().cpu_times()
- assert (times.user > 0.0) or (times.system > 0.0), times
- assert (times.children_user >= 0.0), times
- assert (times.children_system >= 0.0), times
- # make sure returned values can be pretty printed with strftime
- for name in times._fields:
- time.strftime("%H:%M:%S", time.localtime(getattr(times, name)))
-
- def test_cpu_times_2(self):
- user_time, kernel_time = psutil.Process().cpu_times()[:2]
- utime, ktime = os.times()[:2]
-
- # Use os.times()[:2] as base values to compare our results
- # using a tolerance of +/- 0.1 seconds.
- # It will fail if the difference between the values is > 0.1s.
- if (max([user_time, utime]) - min([user_time, utime])) > 0.1:
- self.fail("expected: %s, found: %s" % (utime, user_time))
-
- if (max([kernel_time, ktime]) - min([kernel_time, ktime])) > 0.1:
- self.fail("expected: %s, found: %s" % (ktime, kernel_time))
-
- @unittest.skipIf(not HAS_PROC_CPU_NUM, "not supported")
- def test_cpu_num(self):
- p = psutil.Process()
- num = p.cpu_num()
- self.assertGreaterEqual(num, 0)
- if psutil.cpu_count() == 1:
- self.assertEqual(num, 0)
- self.assertIn(p.cpu_num(), range(psutil.cpu_count()))
-
- def test_create_time(self):
- sproc = get_test_subprocess()
- now = time.time()
- p = psutil.Process(sproc.pid)
- create_time = p.create_time()
-
- # Use time.time() as base value to compare our result using a
- # tolerance of +/- 1 second.
- # It will fail if the difference between the values is > 2s.
- difference = abs(create_time - now)
- if difference > 2:
- self.fail("expected: %s, found: %s, difference: %s"
- % (now, create_time, difference))
-
- # make sure returned value can be pretty printed with strftime
- time.strftime("%Y %m %d %H:%M:%S", time.localtime(p.create_time()))
-
- @unittest.skipIf(not POSIX, 'POSIX only')
- @unittest.skipIf(TRAVIS, 'not reliable on TRAVIS')
- def test_terminal(self):
- terminal = psutil.Process().terminal()
- if sys.stdin.isatty() or sys.stdout.isatty():
- tty = os.path.realpath(sh('tty'))
- self.assertEqual(terminal, tty)
- else:
- self.assertIsNone(terminal)
-
- @unittest.skipIf(not HAS_PROC_IO_COUNTERS, 'not supported')
- @skip_on_not_implemented(only_if=LINUX)
- def test_io_counters(self):
- p = psutil.Process()
-
- # test reads
- io1 = p.io_counters()
- with open(PYTHON_EXE, 'rb') as f:
- f.read()
- io2 = p.io_counters()
- if not BSD and not AIX:
- self.assertGreater(io2.read_count, io1.read_count)
- self.assertEqual(io2.write_count, io1.write_count)
- if LINUX:
- self.assertGreater(io2.read_chars, io1.read_chars)
- self.assertEqual(io2.write_chars, io1.write_chars)
- else:
- self.assertGreaterEqual(io2.read_bytes, io1.read_bytes)
- self.assertGreaterEqual(io2.write_bytes, io1.write_bytes)
-
- # test writes
- io1 = p.io_counters()
- with tempfile.TemporaryFile(prefix=TESTFILE_PREFIX) as f:
- if PY3:
- f.write(bytes("x" * 1000000, 'ascii'))
- else:
- f.write("x" * 1000000)
- io2 = p.io_counters()
- self.assertGreaterEqual(io2.write_count, io1.write_count)
- self.assertGreaterEqual(io2.write_bytes, io1.write_bytes)
- self.assertGreaterEqual(io2.read_count, io1.read_count)
- self.assertGreaterEqual(io2.read_bytes, io1.read_bytes)
- if LINUX:
- self.assertGreater(io2.write_chars, io1.write_chars)
- self.assertGreaterEqual(io2.read_chars, io1.read_chars)
-
- # sanity check
- for i in range(len(io2)):
- if BSD and i >= 2:
- # On BSD read_bytes and write_bytes are always set to -1.
- continue
- self.assertGreaterEqual(io2[i], 0)
- self.assertGreaterEqual(io2[i], 0)
-
- @unittest.skipIf(not HAS_IONICE, "not supported")
- @unittest.skipIf(WINDOWS and get_winver() < WIN_VISTA, 'not supported')
- def test_ionice(self):
- if LINUX:
- from psutil import (IOPRIO_CLASS_NONE, IOPRIO_CLASS_RT,
- IOPRIO_CLASS_BE, IOPRIO_CLASS_IDLE)
- self.assertEqual(IOPRIO_CLASS_NONE, 0)
- self.assertEqual(IOPRIO_CLASS_RT, 1)
- self.assertEqual(IOPRIO_CLASS_BE, 2)
- self.assertEqual(IOPRIO_CLASS_IDLE, 3)
- p = psutil.Process()
- try:
- p.ionice(2)
- ioclass, value = p.ionice()
- if enum is not None:
- self.assertIsInstance(ioclass, enum.IntEnum)
- self.assertEqual(ioclass, 2)
- self.assertEqual(value, 4)
- #
- p.ionice(3)
- ioclass, value = p.ionice()
- self.assertEqual(ioclass, 3)
- self.assertEqual(value, 0)
- #
- p.ionice(2, 0)
- ioclass, value = p.ionice()
- self.assertEqual(ioclass, 2)
- self.assertEqual(value, 0)
- p.ionice(2, 7)
- ioclass, value = p.ionice()
- self.assertEqual(ioclass, 2)
- self.assertEqual(value, 7)
- finally:
- p.ionice(IOPRIO_CLASS_NONE)
- else:
- p = psutil.Process()
- original = p.ionice()
- self.assertIsInstance(original, int)
- try:
- value = 0 # very low
- if original == value:
- value = 1 # low
- p.ionice(value)
- self.assertEqual(p.ionice(), value)
- finally:
- p.ionice(original)
-
- @unittest.skipIf(not HAS_IONICE, "not supported")
- @unittest.skipIf(WINDOWS and get_winver() < WIN_VISTA, 'not supported')
- def test_ionice_errs(self):
- sproc = get_test_subprocess()
- p = psutil.Process(sproc.pid)
- if LINUX:
- self.assertRaises(ValueError, p.ionice, 2, 10)
- self.assertRaises(ValueError, p.ionice, 2, -1)
- self.assertRaises(ValueError, p.ionice, 4)
- self.assertRaises(TypeError, p.ionice, 2, "foo")
- self.assertRaisesRegex(
- ValueError, "can't specify value with IOPRIO_CLASS_NONE",
- p.ionice, psutil.IOPRIO_CLASS_NONE, 1)
- self.assertRaisesRegex(
- ValueError, "can't specify value with IOPRIO_CLASS_IDLE",
- p.ionice, psutil.IOPRIO_CLASS_IDLE, 1)
- self.assertRaisesRegex(
- ValueError, "'ioclass' argument must be specified",
- p.ionice, value=1)
- else:
- self.assertRaises(ValueError, p.ionice, 3)
- self.assertRaises(TypeError, p.ionice, 2, 1)
-
- @unittest.skipIf(not HAS_RLIMIT, "not supported")
- def test_rlimit_get(self):
- import resource
- p = psutil.Process(os.getpid())
- names = [x for x in dir(psutil) if x.startswith('RLIMIT')]
- assert names, names
- for name in names:
- value = getattr(psutil, name)
- self.assertGreaterEqual(value, 0)
- if name in dir(resource):
- self.assertEqual(value, getattr(resource, name))
- # XXX - On PyPy RLIMIT_INFINITY returned by
- # resource.getrlimit() is reported as a very big long
- # number instead of -1. It looks like a bug with PyPy.
- if PYPY:
- continue
- self.assertEqual(p.rlimit(value), resource.getrlimit(value))
- else:
- ret = p.rlimit(value)
- self.assertEqual(len(ret), 2)
- self.assertGreaterEqual(ret[0], -1)
- self.assertGreaterEqual(ret[1], -1)
-
- @unittest.skipIf(not HAS_RLIMIT, "not supported")
- def test_rlimit_set(self):
- sproc = get_test_subprocess()
- p = psutil.Process(sproc.pid)
- p.rlimit(psutil.RLIMIT_NOFILE, (5, 5))
- self.assertEqual(p.rlimit(psutil.RLIMIT_NOFILE), (5, 5))
- # If pid is 0 prlimit() applies to the calling process and
- # we don't want that.
- with self.assertRaises(ValueError):
- psutil._psplatform.Process(0).rlimit(0)
- with self.assertRaises(ValueError):
- p.rlimit(psutil.RLIMIT_NOFILE, (5, 5, 5))
-
- @unittest.skipIf(not HAS_RLIMIT, "not supported")
- def test_rlimit(self):
- p = psutil.Process()
- soft, hard = p.rlimit(psutil.RLIMIT_FSIZE)
- try:
- p.rlimit(psutil.RLIMIT_FSIZE, (1024, hard))
- with open(TESTFN, "wb") as f:
- f.write(b"X" * 1024)
- # write() or flush() doesn't always cause the exception
- # but close() will.
- with self.assertRaises(IOError) as exc:
- with open(TESTFN, "wb") as f:
- f.write(b"X" * 1025)
- self.assertEqual(exc.exception.errno if PY3 else exc.exception[0],
- errno.EFBIG)
- finally:
- p.rlimit(psutil.RLIMIT_FSIZE, (soft, hard))
- self.assertEqual(p.rlimit(psutil.RLIMIT_FSIZE), (soft, hard))
-
- @unittest.skipIf(not HAS_RLIMIT, "not supported")
- def test_rlimit_infinity(self):
- # First set a limit, then re-set it by specifying INFINITY
- # and assume we overridden the previous limit.
- p = psutil.Process()
- soft, hard = p.rlimit(psutil.RLIMIT_FSIZE)
- try:
- p.rlimit(psutil.RLIMIT_FSIZE, (1024, hard))
- p.rlimit(psutil.RLIMIT_FSIZE, (psutil.RLIM_INFINITY, hard))
- with open(TESTFN, "wb") as f:
- f.write(b"X" * 2048)
- finally:
- p.rlimit(psutil.RLIMIT_FSIZE, (soft, hard))
- self.assertEqual(p.rlimit(psutil.RLIMIT_FSIZE), (soft, hard))
-
- @unittest.skipIf(not HAS_RLIMIT, "not supported")
- def test_rlimit_infinity_value(self):
- # RLIMIT_FSIZE should be RLIM_INFINITY, which will be a really
- # big number on a platform with large file support. On these
- # platforms we need to test that the get/setrlimit functions
- # properly convert the number to a C long long and that the
- # conversion doesn't raise an error.
- p = psutil.Process()
- soft, hard = p.rlimit(psutil.RLIMIT_FSIZE)
- self.assertEqual(psutil.RLIM_INFINITY, hard)
- p.rlimit(psutil.RLIMIT_FSIZE, (soft, hard))
-
- def test_num_threads(self):
- # on certain platforms such as Linux we might test for exact
- # thread number, since we always have with 1 thread per process,
- # but this does not apply across all platforms (MACOS, Windows)
- p = psutil.Process()
- if OPENBSD:
- try:
- step1 = p.num_threads()
- except psutil.AccessDenied:
- raise unittest.SkipTest("on OpenBSD this requires root access")
- else:
- step1 = p.num_threads()
-
- with ThreadTask():
- step2 = p.num_threads()
- self.assertEqual(step2, step1 + 1)
-
- @unittest.skipIf(not WINDOWS, 'WINDOWS only')
- def test_num_handles(self):
- # a better test is done later into test/_windows.py
- p = psutil.Process()
- self.assertGreater(p.num_handles(), 0)
-
- @unittest.skipIf(not HAS_THREADS, 'not supported')
- def test_threads(self):
- p = psutil.Process()
- if OPENBSD:
- try:
- step1 = p.threads()
- except psutil.AccessDenied:
- raise unittest.SkipTest("on OpenBSD this requires root access")
- else:
- step1 = p.threads()
-
- with ThreadTask():
- step2 = p.threads()
- self.assertEqual(len(step2), len(step1) + 1)
- # on Linux, first thread id is supposed to be this process
- if LINUX:
- self.assertEqual(step2[0].id, os.getpid())
- athread = step2[0]
- # test named tuple
- self.assertEqual(athread.id, athread[0])
- self.assertEqual(athread.user_time, athread[1])
- self.assertEqual(athread.system_time, athread[2])
-
- @retry_before_failing()
- @skip_on_access_denied(only_if=MACOS)
- @unittest.skipIf(not HAS_THREADS, 'not supported')
- def test_threads_2(self):
- sproc = get_test_subprocess()
- p = psutil.Process(sproc.pid)
- if OPENBSD:
- try:
- p.threads()
- except psutil.AccessDenied:
- raise unittest.SkipTest(
- "on OpenBSD this requires root access")
- self.assertAlmostEqual(
- p.cpu_times().user,
- sum([x.user_time for x in p.threads()]), delta=0.1)
- self.assertAlmostEqual(
- p.cpu_times().system,
- sum([x.system_time for x in p.threads()]), delta=0.1)
-
- def test_memory_info(self):
- p = psutil.Process()
-
- # step 1 - get a base value to compare our results
- rss1, vms1 = p.memory_info()[:2]
- percent1 = p.memory_percent()
- self.assertGreater(rss1, 0)
- self.assertGreater(vms1, 0)
-
- # step 2 - allocate some memory
- memarr = [None] * 1500000
-
- rss2, vms2 = p.memory_info()[:2]
- percent2 = p.memory_percent()
-
- # step 3 - make sure that the memory usage bumped up
- self.assertGreater(rss2, rss1)
- self.assertGreaterEqual(vms2, vms1) # vms might be equal
- self.assertGreater(percent2, percent1)
- del memarr
-
- if WINDOWS:
- mem = p.memory_info()
- self.assertEqual(mem.rss, mem.wset)
- self.assertEqual(mem.vms, mem.pagefile)
-
- mem = p.memory_info()
- for name in mem._fields:
- self.assertGreaterEqual(getattr(mem, name), 0)
-
- def test_memory_full_info(self):
- total = psutil.virtual_memory().total
- mem = psutil.Process().memory_full_info()
- for name in mem._fields:
- value = getattr(mem, name)
- self.assertGreaterEqual(value, 0, msg=(name, value))
- self.assertLessEqual(value, total, msg=(name, value, total))
- if LINUX or WINDOWS or MACOS:
- self.assertGreaterEqual(mem.uss, 0)
- if LINUX:
- self.assertGreaterEqual(mem.pss, 0)
- self.assertGreaterEqual(mem.swap, 0)
-
- @unittest.skipIf(not HAS_MEMORY_MAPS, "not supported")
- def test_memory_maps(self):
- p = psutil.Process()
- maps = p.memory_maps()
- paths = [x for x in maps]
- self.assertEqual(len(paths), len(set(paths)))
- ext_maps = p.memory_maps(grouped=False)
-
- for nt in maps:
- if not nt.path.startswith('['):
- assert os.path.isabs(nt.path), nt.path
- if POSIX:
- try:
- assert os.path.exists(nt.path) or \
- os.path.islink(nt.path), nt.path
- except AssertionError:
- if not LINUX:
- raise
- else:
- # https://github.com/giampaolo/psutil/issues/759
- with open('/proc/self/smaps') as f:
- data = f.read()
- if "%s (deleted)" % nt.path not in data:
- raise
- else:
- # XXX - On Windows we have this strange behavior with
- # 64 bit dlls: they are visible via explorer but cannot
- # be accessed via os.stat() (wtf?).
- if '64' not in os.path.basename(nt.path):
- assert os.path.exists(nt.path), nt.path
- for nt in ext_maps:
- for fname in nt._fields:
- value = getattr(nt, fname)
- if fname == 'path':
- continue
- elif fname in ('addr', 'perms'):
- assert value, value
- else:
- self.assertIsInstance(value, (int, long))
- assert value >= 0, value
-
- @unittest.skipIf(not HAS_MEMORY_MAPS, "not supported")
- def test_memory_maps_lists_lib(self):
- # Make sure a newly loaded shared lib is listed.
- with copyload_shared_lib() as path:
- def normpath(p):
- return os.path.realpath(os.path.normcase(p))
- libpaths = [normpath(x.path)
- for x in psutil.Process().memory_maps()]
- self.assertIn(normpath(path), libpaths)
-
- def test_memory_percent(self):
- p = psutil.Process()
- ret = p.memory_percent()
- assert 0 <= ret <= 100, ret
- ret = p.memory_percent(memtype='vms')
- assert 0 <= ret <= 100, ret
- assert 0 <= ret <= 100, ret
- self.assertRaises(ValueError, p.memory_percent, memtype="?!?")
- if LINUX or MACOS or WINDOWS:
- ret = p.memory_percent(memtype='uss')
- assert 0 <= ret <= 100, ret
- assert 0 <= ret <= 100, ret
-
- def test_is_running(self):
- sproc = get_test_subprocess()
- p = psutil.Process(sproc.pid)
- assert p.is_running()
- assert p.is_running()
- p.kill()
- p.wait()
- assert not p.is_running()
- assert not p.is_running()
-
- def test_exe(self):
- sproc = get_test_subprocess()
- exe = psutil.Process(sproc.pid).exe()
- try:
- self.assertEqual(exe, PYTHON_EXE)
- except AssertionError:
- if WINDOWS and len(exe) == len(PYTHON_EXE):
- # on Windows we don't care about case sensitivity
- normcase = os.path.normcase
- self.assertEqual(normcase(exe), normcase(PYTHON_EXE))
- else:
- # certain platforms such as BSD are more accurate returning:
- # "/usr/local/bin/python2.7"
- # ...instead of:
- # "/usr/local/bin/python"
- # We do not want to consider this difference in accuracy
- # an error.
- ver = "%s.%s" % (sys.version_info[0], sys.version_info[1])
- try:
- self.assertEqual(exe.replace(ver, ''),
- PYTHON_EXE.replace(ver, ''))
- except AssertionError:
- # Tipically MACOS. Really not sure what to do here.
- pass
-
- out = sh([exe, "-c", "import os; print('hey')"])
- self.assertEqual(out, 'hey')
-
- def test_cmdline(self):
- cmdline = [PYTHON_EXE, "-c", "import time; time.sleep(60)"]
- sproc = get_test_subprocess(cmdline)
- try:
- self.assertEqual(' '.join(psutil.Process(sproc.pid).cmdline()),
- ' '.join(cmdline))
- except AssertionError:
- # XXX - most of the times the underlying sysctl() call on Net
- # and Open BSD returns a truncated string.
- # Also /proc/pid/cmdline behaves the same so it looks
- # like this is a kernel bug.
- # XXX - AIX truncates long arguments in /proc/pid/cmdline
- if NETBSD or OPENBSD or AIX:
- self.assertEqual(
- psutil.Process(sproc.pid).cmdline()[0], PYTHON_EXE)
- else:
- raise
-
- def test_name(self):
- sproc = get_test_subprocess(PYTHON_EXE)
- name = psutil.Process(sproc.pid).name().lower()
- pyexe = os.path.basename(os.path.realpath(sys.executable)).lower()
- assert pyexe.startswith(name), (pyexe, name)
-
- # XXX
- @unittest.skipIf(SUNOS, "broken on SUNOS")
- @unittest.skipIf(AIX, "broken on AIX")
- def test_prog_w_funky_name(self):
- # Test that name(), exe() and cmdline() correctly handle programs
- # with funky chars such as spaces and ")", see:
- # https://github.com/giampaolo/psutil/issues/628
-
- def rm():
- # Try to limit occasional failures on Appveyor:
- # https://ci.appveyor.com/project/giampaolo/psutil/build/1350/
- # job/lbo3bkju55le850n
- try:
- safe_rmpath(funky_path)
- except OSError:
- pass
-
- funky_path = TESTFN + 'foo bar )'
- create_exe(funky_path)
- self.addCleanup(rm)
- cmdline = [funky_path, "-c",
- "import time; [time.sleep(0.01) for x in range(3000)];"
- "arg1", "arg2", "", "arg3", ""]
- sproc = get_test_subprocess(cmdline)
- p = psutil.Process(sproc.pid)
- # ...in order to try to prevent occasional failures on travis
- if TRAVIS:
- wait_for_pid(p.pid)
- self.assertEqual(p.cmdline(), cmdline)
- self.assertEqual(p.name(), os.path.basename(funky_path))
- self.assertEqual(os.path.normcase(p.exe()),
- os.path.normcase(funky_path))
-
- @unittest.skipIf(not POSIX, 'POSIX only')
- def test_uids(self):
- p = psutil.Process()
- real, effective, saved = p.uids()
- # os.getuid() refers to "real" uid
- self.assertEqual(real, os.getuid())
- # os.geteuid() refers to "effective" uid
- self.assertEqual(effective, os.geteuid())
- # No such thing as os.getsuid() ("saved" uid), but starting
- # from python 2.7 we have os.getresuid() which returns all
- # of them.
- if hasattr(os, "getresuid"):
- self.assertEqual(os.getresuid(), p.uids())
-
- @unittest.skipIf(not POSIX, 'POSIX only')
- def test_gids(self):
- p = psutil.Process()
- real, effective, saved = p.gids()
- # os.getuid() refers to "real" uid
- self.assertEqual(real, os.getgid())
- # os.geteuid() refers to "effective" uid
- self.assertEqual(effective, os.getegid())
- # No such thing as os.getsgid() ("saved" gid), but starting
- # from python 2.7 we have os.getresgid() which returns all
- # of them.
- if hasattr(os, "getresuid"):
- self.assertEqual(os.getresgid(), p.gids())
-
- def test_nice(self):
- p = psutil.Process()
- self.assertRaises(TypeError, p.nice, "str")
- if WINDOWS:
- try:
- init = p.nice()
- if sys.version_info > (3, 4):
- self.assertIsInstance(init, enum.IntEnum)
- else:
- self.assertIsInstance(init, int)
- self.assertEqual(init, psutil.NORMAL_PRIORITY_CLASS)
- p.nice(psutil.HIGH_PRIORITY_CLASS)
- self.assertEqual(p.nice(), psutil.HIGH_PRIORITY_CLASS)
- p.nice(psutil.NORMAL_PRIORITY_CLASS)
- self.assertEqual(p.nice(), psutil.NORMAL_PRIORITY_CLASS)
- finally:
- p.nice(psutil.NORMAL_PRIORITY_CLASS)
- else:
- first_nice = p.nice()
- try:
- if hasattr(os, "getpriority"):
- self.assertEqual(
- os.getpriority(os.PRIO_PROCESS, os.getpid()), p.nice())
- p.nice(1)
- self.assertEqual(p.nice(), 1)
- if hasattr(os, "getpriority"):
- self.assertEqual(
- os.getpriority(os.PRIO_PROCESS, os.getpid()), p.nice())
- # XXX - going back to previous nice value raises
- # AccessDenied on MACOS
- if not MACOS:
- p.nice(0)
- self.assertEqual(p.nice(), 0)
- except psutil.AccessDenied:
- pass
- finally:
- try:
- p.nice(first_nice)
- except psutil.AccessDenied:
- pass
-
- def test_status(self):
- p = psutil.Process()
- self.assertEqual(p.status(), psutil.STATUS_RUNNING)
-
- def test_username(self):
- sproc = get_test_subprocess()
- p = psutil.Process(sproc.pid)
- username = p.username()
- if WINDOWS:
- domain, username = username.split('\\')
- self.assertEqual(username, getpass.getuser())
- if 'USERDOMAIN' in os.environ:
- self.assertEqual(domain, os.environ['USERDOMAIN'])
- else:
- self.assertEqual(username, getpass.getuser())
-
- def test_cwd(self):
- sproc = get_test_subprocess()
- p = psutil.Process(sproc.pid)
- self.assertEqual(p.cwd(), os.getcwd())
-
- def test_cwd_2(self):
- cmd = [PYTHON_EXE, "-c",
- "import os, time; os.chdir('..'); time.sleep(60)"]
- sproc = get_test_subprocess(cmd)
- p = psutil.Process(sproc.pid)
- call_until(p.cwd, "ret == os.path.dirname(os.getcwd())")
-
- @unittest.skipIf(not HAS_CPU_AFFINITY, 'not supported')
- def test_cpu_affinity(self):
- p = psutil.Process()
- initial = p.cpu_affinity()
- assert initial, initial
- self.addCleanup(p.cpu_affinity, initial)
-
- if hasattr(os, "sched_getaffinity"):
- self.assertEqual(initial, list(os.sched_getaffinity(p.pid)))
- self.assertEqual(len(initial), len(set(initial)))
-
- all_cpus = list(range(len(psutil.cpu_percent(percpu=True))))
- # Work around travis failure:
- # https://travis-ci.org/giampaolo/psutil/builds/284173194
- for n in all_cpus if not TRAVIS else initial:
- p.cpu_affinity([n])
- self.assertEqual(p.cpu_affinity(), [n])
- if hasattr(os, "sched_getaffinity"):
- self.assertEqual(p.cpu_affinity(),
- list(os.sched_getaffinity(p.pid)))
- # also test num_cpu()
- if hasattr(p, "num_cpu"):
- self.assertEqual(p.cpu_affinity()[0], p.num_cpu())
-
- # [] is an alias for "all eligible CPUs"; on Linux this may
- # not be equal to all available CPUs, see:
- # https://github.com/giampaolo/psutil/issues/956
- p.cpu_affinity([])
- if LINUX:
- self.assertEqual(p.cpu_affinity(), p._proc._get_eligible_cpus())
- else:
- self.assertEqual(p.cpu_affinity(), all_cpus)
- if hasattr(os, "sched_getaffinity"):
- self.assertEqual(p.cpu_affinity(),
- list(os.sched_getaffinity(p.pid)))
- #
- self.assertRaises(TypeError, p.cpu_affinity, 1)
- p.cpu_affinity(initial)
- # it should work with all iterables, not only lists
- p.cpu_affinity(set(all_cpus))
- p.cpu_affinity(tuple(all_cpus))
-
- @unittest.skipIf(not HAS_CPU_AFFINITY, 'not supported')
- def test_cpu_affinity_errs(self):
- sproc = get_test_subprocess()
- p = psutil.Process(sproc.pid)
- invalid_cpu = [len(psutil.cpu_times(percpu=True)) + 10]
- self.assertRaises(ValueError, p.cpu_affinity, invalid_cpu)
- self.assertRaises(ValueError, p.cpu_affinity, range(10000, 11000))
- self.assertRaises(TypeError, p.cpu_affinity, [0, "1"])
- self.assertRaises(ValueError, p.cpu_affinity, [0, -1])
-
- @unittest.skipIf(not HAS_CPU_AFFINITY, 'not supported')
- def test_cpu_affinity_all_combinations(self):
- p = psutil.Process()
- initial = p.cpu_affinity()
- assert initial, initial
- self.addCleanup(p.cpu_affinity, initial)
-
- # All possible CPU set combinations.
- combos = []
- for l in range(0, len(initial) + 1):
- for subset in itertools.combinations(initial, l):
- if subset:
- combos.append(list(subset))
-
- for combo in combos:
- p.cpu_affinity(combo)
- self.assertEqual(p.cpu_affinity(), combo)
-
- # TODO: #595
- @unittest.skipIf(BSD, "broken on BSD")
- # can't find any process file on Appveyor
- @unittest.skipIf(APPVEYOR, "unreliable on APPVEYOR")
- def test_open_files(self):
- # current process
- p = psutil.Process()
- files = p.open_files()
- self.assertFalse(TESTFN in files)
- with open(TESTFN, 'wb') as f:
- f.write(b'x' * 1024)
- f.flush()
- # give the kernel some time to see the new file
- files = call_until(p.open_files, "len(ret) != %i" % len(files))
- for file in files:
- if file.path == TESTFN:
- if LINUX:
- self.assertEqual(file.position, 1024)
- break
- else:
- self.fail("no file found; files=%s" % repr(files))
- for file in files:
- assert os.path.isfile(file.path), file
-
- # another process
- cmdline = "import time; f = open(r'%s', 'r'); time.sleep(60);" % TESTFN
- sproc = get_test_subprocess([PYTHON_EXE, "-c", cmdline])
- p = psutil.Process(sproc.pid)
-
- for x in range(100):
- filenames = [x.path for x in p.open_files()]
- if TESTFN in filenames:
- break
- time.sleep(.01)
- else:
- self.assertIn(TESTFN, filenames)
- for file in filenames:
- assert os.path.isfile(file), file
-
- # TODO: #595
- @unittest.skipIf(BSD, "broken on BSD")
- # can't find any process file on Appveyor
- @unittest.skipIf(APPVEYOR, "unreliable on APPVEYOR")
- def test_open_files_2(self):
- # test fd and path fields
- with open(TESTFN, 'w') as fileobj:
- p = psutil.Process()
- for file in p.open_files():
- if file.path == fileobj.name or file.fd == fileobj.fileno():
- break
- else:
- self.fail("no file found; files=%s" % repr(p.open_files()))
- self.assertEqual(file.path, fileobj.name)
- if WINDOWS:
- self.assertEqual(file.fd, -1)
- else:
- self.assertEqual(file.fd, fileobj.fileno())
- # test positions
- ntuple = p.open_files()[0]
- self.assertEqual(ntuple[0], ntuple.path)
- self.assertEqual(ntuple[1], ntuple.fd)
- # test file is gone
- self.assertNotIn(fileobj.name, p.open_files())
-
- @unittest.skipIf(not POSIX, 'POSIX only')
- def test_num_fds(self):
- p = psutil.Process()
- start = p.num_fds()
- file = open(TESTFN, 'w')
- self.addCleanup(file.close)
- self.assertEqual(p.num_fds(), start + 1)
- sock = socket.socket()
- self.addCleanup(sock.close)
- self.assertEqual(p.num_fds(), start + 2)
- file.close()
- sock.close()
- self.assertEqual(p.num_fds(), start)
-
- @skip_on_not_implemented(only_if=LINUX)
- @unittest.skipIf(OPENBSD or NETBSD, "not reliable on OPENBSD & NETBSD")
- def test_num_ctx_switches(self):
- p = psutil.Process()
- before = sum(p.num_ctx_switches())
- for x in range(500000):
- after = sum(p.num_ctx_switches())
- if after > before:
- return
- self.fail("num ctx switches still the same after 50.000 iterations")
-
- def test_ppid(self):
- if hasattr(os, 'getppid'):
- self.assertEqual(psutil.Process().ppid(), os.getppid())
- this_parent = os.getpid()
- sproc = get_test_subprocess()
- p = psutil.Process(sproc.pid)
- self.assertEqual(p.ppid(), this_parent)
- # no other process is supposed to have us as parent
- reap_children(recursive=True)
- if APPVEYOR:
- # Occasional failures, see:
- # https://ci.appveyor.com/project/giampaolo/psutil/build/
- # job/0hs623nenj7w4m33
- return
- for p in psutil.process_iter():
- if p.pid == sproc.pid:
- continue
- # XXX: sometimes this fails on Windows; not sure why.
- self.assertNotEqual(p.ppid(), this_parent, msg=p)
-
- def test_parent(self):
- this_parent = os.getpid()
- sproc = get_test_subprocess()
- p = psutil.Process(sproc.pid)
- self.assertEqual(p.parent().pid, this_parent)
-
- def test_parent_disappeared(self):
- # Emulate a case where the parent process disappeared.
- sproc = get_test_subprocess()
- p = psutil.Process(sproc.pid)
- with mock.patch("psutil.Process",
- side_effect=psutil.NoSuchProcess(0, 'foo')):
- self.assertIsNone(p.parent())
-
- def test_children(self):
- reap_children(recursive=True)
- p = psutil.Process()
- self.assertEqual(p.children(), [])
- self.assertEqual(p.children(recursive=True), [])
- # On Windows we set the flag to 0 in order to cancel out the
- # CREATE_NO_WINDOW flag (enabled by default) which creates
- # an extra "conhost.exe" child.
- sproc = get_test_subprocess(creationflags=0)
- children1 = p.children()
- children2 = p.children(recursive=True)
- for children in (children1, children2):
- self.assertEqual(len(children), 1)
- self.assertEqual(children[0].pid, sproc.pid)
- self.assertEqual(children[0].ppid(), os.getpid())
-
- def test_children_recursive(self):
- # Test children() against two sub processes, p1 and p2, where
- # p1 (our child) spawned p2 (our grandchild).
- p1, p2 = create_proc_children_pair()
- p = psutil.Process()
- self.assertEqual(p.children(), [p1])
- self.assertEqual(p.children(recursive=True), [p1, p2])
- # If the intermediate process is gone there's no way for
- # children() to recursively find it.
- p1.terminate()
- p1.wait()
- self.assertEqual(p.children(recursive=True), [])
-
- def test_children_duplicates(self):
- # find the process which has the highest number of children
- table = collections.defaultdict(int)
- for p in psutil.process_iter():
- try:
- table[p.ppid()] += 1
- except psutil.Error:
- pass
- # this is the one, now let's make sure there are no duplicates
- pid = sorted(table.items(), key=lambda x: x[1])[-1][0]
- p = psutil.Process(pid)
- try:
- c = p.children(recursive=True)
- except psutil.AccessDenied: # windows
- pass
- else:
- self.assertEqual(len(c), len(set(c)))
-
- def test_suspend_resume(self):
- sproc = get_test_subprocess()
- p = psutil.Process(sproc.pid)
- p.suspend()
- for x in range(100):
- if p.status() == psutil.STATUS_STOPPED:
- break
- time.sleep(0.01)
- p.resume()
- self.assertNotEqual(p.status(), psutil.STATUS_STOPPED)
-
- def test_invalid_pid(self):
- self.assertRaises(TypeError, psutil.Process, "1")
- self.assertRaises(ValueError, psutil.Process, -1)
-
- def test_as_dict(self):
- p = psutil.Process()
- d = p.as_dict(attrs=['exe', 'name'])
- self.assertEqual(sorted(d.keys()), ['exe', 'name'])
-
- p = psutil.Process(min(psutil.pids()))
- d = p.as_dict(attrs=['connections'], ad_value='foo')
- if not isinstance(d['connections'], list):
- self.assertEqual(d['connections'], 'foo')
-
- # Test ad_value is set on AccessDenied.
- with mock.patch('psutil.Process.nice', create=True,
- side_effect=psutil.AccessDenied):
- self.assertEqual(
- p.as_dict(attrs=["nice"], ad_value=1), {"nice": 1})
-
- # Test that NoSuchProcess bubbles up.
- with mock.patch('psutil.Process.nice', create=True,
- side_effect=psutil.NoSuchProcess(p.pid, "name")):
- self.assertRaises(
- psutil.NoSuchProcess, p.as_dict, attrs=["nice"])
-
- # Test that ZombieProcess is swallowed.
- with mock.patch('psutil.Process.nice', create=True,
- side_effect=psutil.ZombieProcess(p.pid, "name")):
- self.assertEqual(
- p.as_dict(attrs=["nice"], ad_value="foo"), {"nice": "foo"})
-
- # By default APIs raising NotImplementedError are
- # supposed to be skipped.
- with mock.patch('psutil.Process.nice', create=True,
- side_effect=NotImplementedError):
- d = p.as_dict()
- self.assertNotIn('nice', list(d.keys()))
- # ...unless the user explicitly asked for some attr.
- with self.assertRaises(NotImplementedError):
- p.as_dict(attrs=["nice"])
-
- # errors
- with self.assertRaises(TypeError):
- p.as_dict('name')
- with self.assertRaises(ValueError):
- p.as_dict(['foo'])
- with self.assertRaises(ValueError):
- p.as_dict(['foo', 'bar'])
-
- def test_oneshot(self):
- with mock.patch("psutil._psplatform.Process.cpu_times") as m:
- p = psutil.Process()
- with p.oneshot():
- p.cpu_times()
- p.cpu_times()
- self.assertEqual(m.call_count, 1)
-
- with mock.patch("psutil._psplatform.Process.cpu_times") as m:
- p.cpu_times()
- p.cpu_times()
- self.assertEqual(m.call_count, 2)
-
- def test_oneshot_twice(self):
- # Test the case where the ctx manager is __enter__ed twice.
- # The second __enter__ is supposed to resut in a NOOP.
- with mock.patch("psutil._psplatform.Process.cpu_times") as m1:
- with mock.patch("psutil._psplatform.Process.oneshot_enter") as m2:
- p = psutil.Process()
- with p.oneshot():
- p.cpu_times()
- p.cpu_times()
- with p.oneshot():
- p.cpu_times()
- p.cpu_times()
- self.assertEqual(m1.call_count, 1)
- self.assertEqual(m2.call_count, 1)
-
- with mock.patch("psutil._psplatform.Process.cpu_times") as m:
- p.cpu_times()
- p.cpu_times()
- self.assertEqual(m.call_count, 2)
-
- def test_halfway_terminated_process(self):
- # Test that NoSuchProcess exception gets raised in case the
- # process dies after we create the Process object.
- # Example:
- # >>> proc = Process(1234)
- # >>> time.sleep(2) # time-consuming task, process dies in meantime
- # >>> proc.name()
- # Refers to Issue #15
- sproc = get_test_subprocess()
- p = psutil.Process(sproc.pid)
- p.terminate()
- p.wait()
- if WINDOWS:
- call_until(psutil.pids, "%s not in ret" % p.pid)
- self.assertFalse(p.is_running())
- # self.assertFalse(p.pid in psutil.pids(), msg="retcode = %s" %
- # retcode)
-
- excluded_names = ['pid', 'is_running', 'wait', 'create_time',
- 'oneshot', 'memory_info_ex']
- if LINUX and not HAS_RLIMIT:
- excluded_names.append('rlimit')
- for name in dir(p):
- if (name.startswith('_') or
- name in excluded_names):
- continue
- try:
- meth = getattr(p, name)
- # get/set methods
- if name == 'nice':
- if POSIX:
- ret = meth(1)
- else:
- ret = meth(psutil.NORMAL_PRIORITY_CLASS)
- elif name == 'ionice':
- ret = meth()
- ret = meth(2)
- elif name == 'rlimit':
- ret = meth(psutil.RLIMIT_NOFILE)
- ret = meth(psutil.RLIMIT_NOFILE, (5, 5))
- elif name == 'cpu_affinity':
- ret = meth()
- ret = meth([0])
- elif name == 'send_signal':
- ret = meth(signal.SIGTERM)
- else:
- ret = meth()
- except psutil.ZombieProcess:
- self.fail("ZombieProcess for %r was not supposed to happen" %
- name)
- except psutil.NoSuchProcess:
- pass
- except psutil.AccessDenied:
- if OPENBSD and name in ('threads', 'num_threads'):
- pass
- else:
- raise
- except NotImplementedError:
- pass
- else:
- self.fail(
- "NoSuchProcess exception not raised for %r, retval=%s" % (
- name, ret))
-
- @unittest.skipIf(not POSIX, 'POSIX only')
- def test_zombie_process(self):
- def succeed_or_zombie_p_exc(fun, *args, **kwargs):
- try:
- return fun(*args, **kwargs)
- except (psutil.ZombieProcess, psutil.AccessDenied):
- pass
-
- zpid = create_zombie_proc()
- self.addCleanup(reap_children, recursive=True)
- # A zombie process should always be instantiable
- zproc = psutil.Process(zpid)
- # ...and at least its status always be querable
- self.assertEqual(zproc.status(), psutil.STATUS_ZOMBIE)
- # ...and it should be considered 'running'
- self.assertTrue(zproc.is_running())
- # ...and as_dict() shouldn't crash
- zproc.as_dict()
- # if cmdline succeeds it should be an empty list
- ret = succeed_or_zombie_p_exc(zproc.suspend)
- if ret is not None:
- self.assertEqual(ret, [])
-
- if hasattr(zproc, "rlimit"):
- succeed_or_zombie_p_exc(zproc.rlimit, psutil.RLIMIT_NOFILE)
- succeed_or_zombie_p_exc(zproc.rlimit, psutil.RLIMIT_NOFILE,
- (5, 5))
- # set methods
- succeed_or_zombie_p_exc(zproc.parent)
- if hasattr(zproc, 'cpu_affinity'):
- try:
- succeed_or_zombie_p_exc(zproc.cpu_affinity, [0])
- except ValueError as err:
- if TRAVIS and LINUX and "not eligible" in str(err):
- # https://travis-ci.org/giampaolo/psutil/jobs/279890461
- pass
- else:
- raise
-
- succeed_or_zombie_p_exc(zproc.nice, 0)
- if hasattr(zproc, 'ionice'):
- if LINUX:
- succeed_or_zombie_p_exc(zproc.ionice, 2, 0)
- else:
- succeed_or_zombie_p_exc(zproc.ionice, 0) # Windows
- if hasattr(zproc, 'rlimit'):
- succeed_or_zombie_p_exc(zproc.rlimit,
- psutil.RLIMIT_NOFILE, (5, 5))
- succeed_or_zombie_p_exc(zproc.suspend)
- succeed_or_zombie_p_exc(zproc.resume)
- succeed_or_zombie_p_exc(zproc.terminate)
- succeed_or_zombie_p_exc(zproc.kill)
-
- # ...its parent should 'see' it
- # edit: not true on BSD and MACOS
- # descendants = [x.pid for x in psutil.Process().children(
- # recursive=True)]
- # self.assertIn(zpid, descendants)
- # XXX should we also assume ppid be usable? Note: this
- # would be an important use case as the only way to get
- # rid of a zombie is to kill its parent.
- # self.assertEqual(zpid.ppid(), os.getpid())
- # ...and all other APIs should be able to deal with it
- self.assertTrue(psutil.pid_exists(zpid))
- if not TRAVIS and MACOS:
- # For some reason this started failing all of the sudden.
- # Maybe they upgraded MACOS version?
- # https://travis-ci.org/giampaolo/psutil/jobs/310896404
- self.assertIn(zpid, psutil.pids())
- self.assertIn(zpid, [x.pid for x in psutil.process_iter()])
- psutil._pmap = {}
- self.assertIn(zpid, [x.pid for x in psutil.process_iter()])
-
- @unittest.skipIf(not POSIX, 'POSIX only')
- def test_zombie_process_is_running_w_exc(self):
- # Emulate a case where internally is_running() raises
- # ZombieProcess.
- p = psutil.Process()
- with mock.patch("psutil.Process",
- side_effect=psutil.ZombieProcess(0)) as m:
- assert p.is_running()
- assert m.called
-
- @unittest.skipIf(not POSIX, 'POSIX only')
- def test_zombie_process_status_w_exc(self):
- # Emulate a case where internally status() raises
- # ZombieProcess.
- p = psutil.Process()
- with mock.patch("psutil._psplatform.Process.status",
- side_effect=psutil.ZombieProcess(0)) as m:
- self.assertEqual(p.status(), psutil.STATUS_ZOMBIE)
- assert m.called
-
- def test_pid_0(self):
- # Process(0) is supposed to work on all platforms except Linux
- if 0 not in psutil.pids():
- self.assertRaises(psutil.NoSuchProcess, psutil.Process, 0)
- return
-
- # test all methods
- p = psutil.Process(0)
- for name in psutil._as_dict_attrnames:
- if name == 'pid':
- continue
- meth = getattr(p, name)
- try:
- ret = meth()
- except psutil.AccessDenied:
- pass
- else:
- if name in ("uids", "gids"):
- self.assertEqual(ret.real, 0)
- elif name == "username":
- if POSIX:
- self.assertEqual(p.username(), 'root')
- elif WINDOWS:
- self.assertEqual(p.username(), 'NT AUTHORITY\\SYSTEM')
- elif name == "name":
- assert name, name
-
- if hasattr(p, 'rlimit'):
- try:
- p.rlimit(psutil.RLIMIT_FSIZE)
- except psutil.AccessDenied:
- pass
-
- p.as_dict()
-
- if not OPENBSD:
- self.assertIn(0, psutil.pids())
- self.assertTrue(psutil.pid_exists(0))
-
- @unittest.skipIf(not HAS_ENVIRON, "not supported")
- def test_environ(self):
- def clean_dict(d):
- # Most of these are problematic on Travis.
- d.pop("PSUTIL_TESTING", None)
- d.pop("PLAT", None)
- d.pop("HOME", None)
- if MACOS:
- d.pop("__CF_USER_TEXT_ENCODING", None)
- d.pop("VERSIONER_PYTHON_PREFER_32_BIT", None)
- d.pop("VERSIONER_PYTHON_VERSION", None)
- return dict(
- [(k.replace("\r", "").replace("\n", ""),
- v.replace("\r", "").replace("\n", ""))
- for k, v in d.items()])
-
- self.maxDiff = None
- p = psutil.Process()
- d1 = clean_dict(p.environ())
- d2 = clean_dict(os.environ.copy())
- self.assertEqual(d1, d2)
-
- @unittest.skipIf(not HAS_ENVIRON, "not supported")
- @unittest.skipIf(not POSIX, "POSIX only")
- def test_weird_environ(self):
- # environment variables can contain values without an equals sign
- code = textwrap.dedent("""
- #include
- #include
- char * const argv[] = {"cat", 0};
- char * const envp[] = {"A=1", "X", "C=3", 0};
- int main(void) {
- /* Close stderr on exec so parent can wait for the execve to
- * finish. */
- if (fcntl(2, F_SETFD, FD_CLOEXEC) != 0)
- return 0;
- return execve("/bin/cat", argv, envp);
- }
- """)
- path = TESTFN
- create_exe(path, c_code=code)
- self.addCleanup(safe_rmpath, path)
- sproc = get_test_subprocess([path],
- stdin=subprocess.PIPE,
- stderr=subprocess.PIPE)
- p = psutil.Process(sproc.pid)
- wait_for_pid(p.pid)
- self.assertTrue(p.is_running())
- # Wait for process to exec or exit.
- self.assertEqual(sproc.stderr.read(), b"")
- self.assertEqual(p.environ(), {"A": "1", "C": "3"})
- sproc.communicate()
- self.assertEqual(sproc.returncode, 0)
-
-
-# ===================================================================
-# --- Limited user tests
-# ===================================================================
-
-
-if POSIX and os.getuid() == 0:
- class LimitedUserTestCase(TestProcess):
- """Repeat the previous tests by using a limited user.
- Executed only on UNIX and only if the user who run the test script
- is root.
- """
- # the uid/gid the test suite runs under
- if hasattr(os, 'getuid'):
- PROCESS_UID = os.getuid()
- PROCESS_GID = os.getgid()
-
- def __init__(self, *args, **kwargs):
- TestProcess.__init__(self, *args, **kwargs)
- # re-define all existent test methods in order to
- # ignore AccessDenied exceptions
- for attr in [x for x in dir(self) if x.startswith('test')]:
- meth = getattr(self, attr)
-
- def test_(self):
- try:
- meth()
- except psutil.AccessDenied:
- pass
- setattr(self, attr, types.MethodType(test_, self))
-
- def setUp(self):
- safe_rmpath(TESTFN)
- TestProcess.setUp(self)
- os.setegid(1000)
- os.seteuid(1000)
-
- def tearDown(self):
- os.setegid(self.PROCESS_UID)
- os.seteuid(self.PROCESS_GID)
- TestProcess.tearDown(self)
-
- def test_nice(self):
- try:
- psutil.Process().nice(-1)
- except psutil.AccessDenied:
- pass
- else:
- self.fail("exception not raised")
-
- def test_zombie_process(self):
- # causes problems if test test suite is run as root
- pass
-
-
-# ===================================================================
-# --- psutil.Popen tests
-# ===================================================================
-
-
-class TestPopen(unittest.TestCase):
- """Tests for psutil.Popen class."""
-
- def tearDown(self):
- reap_children()
-
- def test_misc(self):
- # XXX this test causes a ResourceWarning on Python 3 because
- # psutil.__subproc instance doesn't get propertly freed.
- # Not sure what to do though.
- cmd = [PYTHON_EXE, "-c", "import time; time.sleep(60);"]
- with psutil.Popen(cmd, stdout=subprocess.PIPE,
- stderr=subprocess.PIPE) as proc:
- proc.name()
- proc.cpu_times()
- proc.stdin
- self.assertTrue(dir(proc))
- self.assertRaises(AttributeError, getattr, proc, 'foo')
- proc.terminate()
-
- def test_ctx_manager(self):
- with psutil.Popen([PYTHON_EXE, "-V"],
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE,
- stdin=subprocess.PIPE) as proc:
- proc.communicate()
- assert proc.stdout.closed
- assert proc.stderr.closed
- assert proc.stdin.closed
- self.assertEqual(proc.returncode, 0)
-
- def test_kill_terminate(self):
- # subprocess.Popen()'s terminate(), kill() and send_signal() do
- # not raise exception after the process is gone. psutil.Popen
- # diverges from that.
- cmd = [PYTHON_EXE, "-c", "import time; time.sleep(60);"]
- with psutil.Popen(cmd, stdout=subprocess.PIPE,
- stderr=subprocess.PIPE) as proc:
- proc.terminate()
- proc.wait()
- self.assertRaises(psutil.NoSuchProcess, proc.terminate)
- self.assertRaises(psutil.NoSuchProcess, proc.kill)
- self.assertRaises(psutil.NoSuchProcess, proc.send_signal,
- signal.SIGTERM)
- if WINDOWS and sys.version_info >= (2, 7):
- self.assertRaises(psutil.NoSuchProcess, proc.send_signal,
- signal.CTRL_C_EVENT)
- self.assertRaises(psutil.NoSuchProcess, proc.send_signal,
- signal.CTRL_BREAK_EVENT)
-
-
-if __name__ == '__main__':
- run_test_module_by_name(__file__)
diff --git a/server/www/packages/packages-darwin/x64/psutil/tests/test_sunos.py b/server/www/packages/packages-darwin/x64/psutil/tests/test_sunos.py
deleted file mode 100644
index ea9afcd..0000000
--- a/server/www/packages/packages-darwin/x64/psutil/tests/test_sunos.py
+++ /dev/null
@@ -1,45 +0,0 @@
-#!/usr/bin/env python
-
-# 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.
-
-"""Sun OS specific tests."""
-
-import os
-
-import psutil
-from psutil import SUNOS
-from psutil.tests import run_test_module_by_name
-from psutil.tests import sh
-from psutil.tests import unittest
-
-
-@unittest.skipIf(not SUNOS, "SUNOS only")
-class SunOSSpecificTestCase(unittest.TestCase):
-
- def test_swap_memory(self):
- out = sh('env PATH=/usr/sbin:/sbin:%s swap -l' % os.environ['PATH'])
- lines = out.strip().split('\n')[1:]
- if not lines:
- raise ValueError('no swap device(s) configured')
- total = free = 0
- for line in lines:
- line = line.split()
- t, f = line[-2:]
- total += int(int(t) * 512)
- free += int(int(f) * 512)
- used = total - free
-
- psutil_swap = psutil.swap_memory()
- self.assertEqual(psutil_swap.total, total)
- self.assertEqual(psutil_swap.used, used)
- self.assertEqual(psutil_swap.free, free)
-
- def test_cpu_count(self):
- out = sh("/usr/sbin/psrinfo")
- self.assertEqual(psutil.cpu_count(), len(out.split('\n')))
-
-
-if __name__ == '__main__':
- run_test_module_by_name(__file__)
diff --git a/server/www/packages/packages-darwin/x64/psutil/tests/test_system.py b/server/www/packages/packages-darwin/x64/psutil/tests/test_system.py
deleted file mode 100644
index f9006ce..0000000
--- a/server/www/packages/packages-darwin/x64/psutil/tests/test_system.py
+++ /dev/null
@@ -1,869 +0,0 @@
-#!/usr/bin/env python
-
-# 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.
-
-"""Tests for system APIS."""
-
-import contextlib
-import datetime
-import errno
-import os
-import pprint
-import shutil
-import signal
-import socket
-import sys
-import tempfile
-import time
-
-import psutil
-from psutil import AIX
-from psutil import BSD
-from psutil import FREEBSD
-from psutil import LINUX
-from psutil import MACOS
-from psutil import NETBSD
-from psutil import OPENBSD
-from psutil import POSIX
-from psutil import SUNOS
-from psutil import WINDOWS
-from psutil._compat import long
-from psutil.tests import APPVEYOR
-from psutil.tests import ASCII_FS
-from psutil.tests import check_net_address
-from psutil.tests import DEVNULL
-from psutil.tests import enum
-from psutil.tests import get_test_subprocess
-from psutil.tests import HAS_BATTERY
-from psutil.tests import HAS_CPU_FREQ
-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 mock
-from psutil.tests import reap_children
-from psutil.tests import retry_before_failing
-from psutil.tests import run_test_module_by_name
-from psutil.tests import safe_rmpath
-from psutil.tests import TESTFN
-from psutil.tests import TESTFN_UNICODE
-from psutil.tests import TRAVIS
-from psutil.tests import unittest
-
-
-# ===================================================================
-# --- System-related API tests
-# ===================================================================
-
-
-class TestSystemAPIs(unittest.TestCase):
- """Tests for system-related APIs."""
-
- def setUp(self):
- safe_rmpath(TESTFN)
-
- def tearDown(self):
- reap_children()
-
- def test_process_iter(self):
- self.assertIn(os.getpid(), [x.pid for x in psutil.process_iter()])
- sproc = get_test_subprocess()
- self.assertIn(sproc.pid, [x.pid for x in psutil.process_iter()])
- p = psutil.Process(sproc.pid)
- p.kill()
- p.wait()
- self.assertNotIn(sproc.pid, [x.pid for x in psutil.process_iter()])
-
- with mock.patch('psutil.Process',
- side_effect=psutil.NoSuchProcess(os.getpid())):
- self.assertEqual(list(psutil.process_iter()), [])
- with mock.patch('psutil.Process',
- side_effect=psutil.AccessDenied(os.getpid())):
- with self.assertRaises(psutil.AccessDenied):
- list(psutil.process_iter())
-
- def test_prcess_iter_w_params(self):
- for p in psutil.process_iter(attrs=['pid']):
- self.assertEqual(list(p.info.keys()), ['pid'])
- with self.assertRaises(ValueError):
- list(psutil.process_iter(attrs=['foo']))
- with mock.patch("psutil._psplatform.Process.cpu_times",
- side_effect=psutil.AccessDenied(0, "")) as m:
- for p in psutil.process_iter(attrs=["pid", "cpu_times"]):
- self.assertIsNone(p.info['cpu_times'])
- self.assertGreaterEqual(p.info['pid'], 0)
- assert m.called
- with mock.patch("psutil._psplatform.Process.cpu_times",
- side_effect=psutil.AccessDenied(0, "")) as m:
- flag = object()
- for p in psutil.process_iter(
- attrs=["pid", "cpu_times"], ad_value=flag):
- self.assertIs(p.info['cpu_times'], flag)
- self.assertGreaterEqual(p.info['pid'], 0)
- assert m.called
-
- def test_wait_procs(self):
- def callback(p):
- pids.append(p.pid)
-
- pids = []
- sproc1 = get_test_subprocess()
- sproc2 = get_test_subprocess()
- sproc3 = get_test_subprocess()
- procs = [psutil.Process(x.pid) for x in (sproc1, sproc2, sproc3)]
- self.assertRaises(ValueError, psutil.wait_procs, procs, timeout=-1)
- self.assertRaises(TypeError, psutil.wait_procs, procs, callback=1)
- t = time.time()
- gone, alive = psutil.wait_procs(procs, timeout=0.01, callback=callback)
-
- self.assertLess(time.time() - t, 0.5)
- self.assertEqual(gone, [])
- self.assertEqual(len(alive), 3)
- self.assertEqual(pids, [])
- for p in alive:
- self.assertFalse(hasattr(p, 'returncode'))
-
- @retry_before_failing(30)
- def test(procs, callback):
- gone, alive = psutil.wait_procs(procs, timeout=0.03,
- callback=callback)
- self.assertEqual(len(gone), 1)
- self.assertEqual(len(alive), 2)
- return gone, alive
-
- sproc3.terminate()
- gone, alive = test(procs, callback)
- self.assertIn(sproc3.pid, [x.pid for x in gone])
- if POSIX:
- self.assertEqual(gone.pop().returncode, -signal.SIGTERM)
- else:
- self.assertEqual(gone.pop().returncode, 1)
- self.assertEqual(pids, [sproc3.pid])
- for p in alive:
- self.assertFalse(hasattr(p, 'returncode'))
-
- @retry_before_failing(30)
- def test(procs, callback):
- gone, alive = psutil.wait_procs(procs, timeout=0.03,
- callback=callback)
- self.assertEqual(len(gone), 3)
- self.assertEqual(len(alive), 0)
- return gone, alive
-
- sproc1.terminate()
- sproc2.terminate()
- gone, alive = test(procs, callback)
- self.assertEqual(set(pids), set([sproc1.pid, sproc2.pid, sproc3.pid]))
- for p in gone:
- self.assertTrue(hasattr(p, 'returncode'))
-
- def test_wait_procs_no_timeout(self):
- sproc1 = get_test_subprocess()
- sproc2 = get_test_subprocess()
- sproc3 = get_test_subprocess()
- procs = [psutil.Process(x.pid) for x in (sproc1, sproc2, sproc3)]
- for p in procs:
- p.terminate()
- gone, alive = psutil.wait_procs(procs)
-
- def test_boot_time(self):
- bt = psutil.boot_time()
- self.assertIsInstance(bt, float)
- self.assertGreater(bt, 0)
- self.assertLess(bt, time.time())
-
- @unittest.skipIf(not POSIX, 'POSIX only')
- def test_PAGESIZE(self):
- # pagesize is used internally to perform different calculations
- # and it's determined by using SC_PAGE_SIZE; make sure
- # getpagesize() returns the same value.
- import resource
- self.assertEqual(os.sysconf("SC_PAGE_SIZE"), resource.getpagesize())
-
- def test_virtual_memory(self):
- mem = psutil.virtual_memory()
- assert mem.total > 0, mem
- assert mem.available > 0, mem
- assert 0 <= mem.percent <= 100, mem
- assert mem.used > 0, mem
- assert mem.free >= 0, mem
- for name in mem._fields:
- value = getattr(mem, name)
- if name != 'percent':
- self.assertIsInstance(value, (int, long))
- if name != 'total':
- if not value >= 0:
- self.fail("%r < 0 (%s)" % (name, value))
- if value > mem.total:
- self.fail("%r > total (total=%s, %s=%s)"
- % (name, mem.total, name, value))
-
- def test_swap_memory(self):
- mem = psutil.swap_memory()
- self.assertEqual(
- mem._fields, ('total', 'used', 'free', 'percent', 'sin', 'sout'))
-
- assert mem.total >= 0, mem
- assert mem.used >= 0, mem
- if mem.total > 0:
- # likely a system with no swap partition
- assert mem.free > 0, mem
- else:
- assert mem.free == 0, mem
- assert 0 <= mem.percent <= 100, mem
- assert mem.sin >= 0, mem
- assert mem.sout >= 0, mem
-
- def test_pid_exists(self):
- sproc = get_test_subprocess()
- self.assertTrue(psutil.pid_exists(sproc.pid))
- p = psutil.Process(sproc.pid)
- p.kill()
- p.wait()
- self.assertFalse(psutil.pid_exists(sproc.pid))
- self.assertFalse(psutil.pid_exists(-1))
- self.assertEqual(psutil.pid_exists(0), 0 in psutil.pids())
-
- def test_pid_exists_2(self):
- reap_children()
- pids = psutil.pids()
- for pid in pids:
- try:
- assert psutil.pid_exists(pid)
- except AssertionError:
- # in case the process disappeared in meantime fail only
- # if it is no longer in psutil.pids()
- time.sleep(.1)
- if pid in psutil.pids():
- self.fail(pid)
- pids = range(max(pids) + 5000, max(pids) + 6000)
- for pid in pids:
- self.assertFalse(psutil.pid_exists(pid), msg=pid)
-
- def test_pids(self):
- plist = [x.pid for x in psutil.process_iter()]
- pidlist = psutil.pids()
- self.assertEqual(plist.sort(), pidlist.sort())
- # make sure every pid is unique
- self.assertEqual(len(pidlist), len(set(pidlist)))
-
- def test_test(self):
- # test for psutil.test() function
- stdout = sys.stdout
- sys.stdout = DEVNULL
- try:
- psutil.test()
- finally:
- sys.stdout = stdout
-
- def test_cpu_count(self):
- logical = psutil.cpu_count()
- self.assertEqual(logical, len(psutil.cpu_times(percpu=True)))
- self.assertGreaterEqual(logical, 1)
- #
- if os.path.exists("/proc/cpuinfo"):
- with open("/proc/cpuinfo") as fd:
- cpuinfo_data = fd.read()
- if "physical id" not in cpuinfo_data:
- raise unittest.SkipTest("cpuinfo doesn't include physical id")
- physical = psutil.cpu_count(logical=False)
- if WINDOWS and sys.getwindowsversion()[:2] <= (6, 1): # <= Vista
- self.assertIsNone(physical)
- else:
- self.assertGreaterEqual(physical, 1)
- self.assertGreaterEqual(logical, physical)
-
- def test_cpu_count_none(self):
- # https://github.com/giampaolo/psutil/issues/1085
- for val in (-1, 0, None):
- with mock.patch('psutil._psplatform.cpu_count_logical',
- return_value=val) as m:
- self.assertIsNone(psutil.cpu_count())
- assert m.called
- with mock.patch('psutil._psplatform.cpu_count_physical',
- return_value=val) as m:
- self.assertIsNone(psutil.cpu_count(logical=False))
- assert m.called
-
- def test_cpu_times(self):
- # Check type, value >= 0, str().
- total = 0
- times = psutil.cpu_times()
- sum(times)
- for cp_time in times:
- self.assertIsInstance(cp_time, float)
- self.assertGreaterEqual(cp_time, 0.0)
- total += cp_time
- self.assertEqual(total, sum(times))
- str(times)
- # CPU times are always supposed to increase over time
- # or at least remain the same and that's because time
- # cannot go backwards.
- # Surprisingly sometimes this might not be the case (at
- # least on Windows and Linux), see:
- # https://github.com/giampaolo/psutil/issues/392
- # https://github.com/giampaolo/psutil/issues/645
- # if not WINDOWS:
- # last = psutil.cpu_times()
- # for x in range(100):
- # new = psutil.cpu_times()
- # for field in new._fields:
- # new_t = getattr(new, field)
- # last_t = getattr(last, field)
- # self.assertGreaterEqual(new_t, last_t,
- # msg="%s %s" % (new_t, last_t))
- # last = new
-
- def test_cpu_times_time_increases(self):
- # Make sure time increases between calls.
- t1 = sum(psutil.cpu_times())
- time.sleep(0.1)
- t2 = sum(psutil.cpu_times())
- difference = t2 - t1
- if not difference >= 0.05:
- self.fail("difference %s" % difference)
-
- def test_per_cpu_times(self):
- # Check type, value >= 0, str().
- for times in psutil.cpu_times(percpu=True):
- total = 0
- sum(times)
- for cp_time in times:
- self.assertIsInstance(cp_time, float)
- self.assertGreaterEqual(cp_time, 0.0)
- total += cp_time
- self.assertEqual(total, sum(times))
- str(times)
- self.assertEqual(len(psutil.cpu_times(percpu=True)[0]),
- len(psutil.cpu_times(percpu=False)))
-
- # Note: in theory CPU times are always supposed to increase over
- # time or remain the same but never go backwards. In practice
- # sometimes this is not the case.
- # This issue seemd to be afflict Windows:
- # https://github.com/giampaolo/psutil/issues/392
- # ...but it turns out also Linux (rarely) behaves the same.
- # last = psutil.cpu_times(percpu=True)
- # for x in range(100):
- # new = psutil.cpu_times(percpu=True)
- # for index in range(len(new)):
- # newcpu = new[index]
- # lastcpu = last[index]
- # for field in newcpu._fields:
- # new_t = getattr(newcpu, field)
- # last_t = getattr(lastcpu, field)
- # self.assertGreaterEqual(
- # new_t, last_t, msg="%s %s" % (lastcpu, newcpu))
- # last = new
-
- def test_per_cpu_times_2(self):
- # Simulate some work load then make sure time have increased
- # between calls.
- tot1 = psutil.cpu_times(percpu=True)
- stop_at = time.time() + 0.1
- while True:
- if time.time() >= stop_at:
- break
- tot2 = psutil.cpu_times(percpu=True)
- for t1, t2 in zip(tot1, tot2):
- t1, t2 = sum(t1), sum(t2)
- difference = t2 - t1
- if difference >= 0.05:
- return
- self.fail()
-
- def test_cpu_times_comparison(self):
- # Make sure the sum of all per cpu times is almost equal to
- # base "one cpu" times.
- base = psutil.cpu_times()
- per_cpu = psutil.cpu_times(percpu=True)
- summed_values = base._make([sum(num) for num in zip(*per_cpu)])
- for field in base._fields:
- self.assertAlmostEqual(
- getattr(base, field), getattr(summed_values, field), delta=1)
-
- def _test_cpu_percent(self, percent, last_ret, new_ret):
- try:
- self.assertIsInstance(percent, float)
- self.assertGreaterEqual(percent, 0.0)
- self.assertIsNot(percent, -0.0)
- self.assertLessEqual(percent, 100.0 * psutil.cpu_count())
- except AssertionError as err:
- raise AssertionError("\n%s\nlast=%s\nnew=%s" % (
- err, pprint.pformat(last_ret), pprint.pformat(new_ret)))
-
- def test_cpu_percent(self):
- last = psutil.cpu_percent(interval=0.001)
- for x in range(100):
- new = psutil.cpu_percent(interval=None)
- self._test_cpu_percent(new, last, new)
- last = new
- with self.assertRaises(ValueError):
- psutil.cpu_percent(interval=-1)
-
- def test_per_cpu_percent(self):
- last = psutil.cpu_percent(interval=0.001, percpu=True)
- self.assertEqual(len(last), psutil.cpu_count())
- for x in range(100):
- new = psutil.cpu_percent(interval=None, percpu=True)
- for percent in new:
- self._test_cpu_percent(percent, last, new)
- last = new
- with self.assertRaises(ValueError):
- psutil.cpu_percent(interval=-1, percpu=True)
-
- def test_cpu_times_percent(self):
- last = psutil.cpu_times_percent(interval=0.001)
- for x in range(100):
- new = psutil.cpu_times_percent(interval=None)
- for percent in new:
- self._test_cpu_percent(percent, last, new)
- self._test_cpu_percent(sum(new), last, new)
- last = new
-
- def test_per_cpu_times_percent(self):
- last = psutil.cpu_times_percent(interval=0.001, percpu=True)
- self.assertEqual(len(last), psutil.cpu_count())
- for x in range(100):
- new = psutil.cpu_times_percent(interval=None, percpu=True)
- for cpu in new:
- for percent in cpu:
- self._test_cpu_percent(percent, last, new)
- self._test_cpu_percent(sum(cpu), last, new)
- last = new
-
- def test_per_cpu_times_percent_negative(self):
- # see: https://github.com/giampaolo/psutil/issues/645
- psutil.cpu_times_percent(percpu=True)
- zero_times = [x._make([0 for x in range(len(x._fields))])
- for x in psutil.cpu_times(percpu=True)]
- with mock.patch('psutil.cpu_times', return_value=zero_times):
- for cpu in psutil.cpu_times_percent(percpu=True):
- for percent in cpu:
- self._test_cpu_percent(percent, None, None)
-
- def test_disk_usage(self):
- usage = psutil.disk_usage(os.getcwd())
- self.assertEqual(usage._fields, ('total', 'used', 'free', 'percent'))
-
- assert usage.total > 0, usage
- assert usage.used > 0, usage
- assert usage.free > 0, usage
- assert usage.total > usage.used, usage
- assert usage.total > usage.free, usage
- assert 0 <= usage.percent <= 100, usage.percent
- if hasattr(shutil, 'disk_usage'):
- # py >= 3.3, see: http://bugs.python.org/issue12442
- shutil_usage = shutil.disk_usage(os.getcwd())
- tolerance = 5 * 1024 * 1024 # 5MB
- self.assertEqual(usage.total, shutil_usage.total)
- self.assertAlmostEqual(usage.free, shutil_usage.free,
- delta=tolerance)
- self.assertAlmostEqual(usage.used, shutil_usage.used,
- delta=tolerance)
-
- # if path does not exist OSError ENOENT is expected across
- # all platforms
- fname = tempfile.mktemp()
- with self.assertRaises(OSError) as exc:
- psutil.disk_usage(fname)
- self.assertEqual(exc.exception.errno, errno.ENOENT)
-
- def test_disk_usage_unicode(self):
- # See: https://github.com/giampaolo/psutil/issues/416
- if ASCII_FS:
- with self.assertRaises(UnicodeEncodeError):
- psutil.disk_usage(TESTFN_UNICODE)
-
- def test_disk_usage_bytes(self):
- psutil.disk_usage(b'.')
-
- def test_disk_partitions(self):
- # all = False
- ls = psutil.disk_partitions(all=False)
- # on travis we get:
- # self.assertEqual(p.cpu_affinity(), [n])
- # AssertionError: Lists differ: [0, 1, 2, 3, 4, 5, 6, 7,... != [0]
- self.assertTrue(ls, msg=ls)
- for disk in ls:
- self.assertIsInstance(disk.device, str)
- self.assertIsInstance(disk.mountpoint, str)
- self.assertIsInstance(disk.fstype, str)
- self.assertIsInstance(disk.opts, str)
- if WINDOWS and 'cdrom' in disk.opts:
- continue
- if not POSIX:
- assert os.path.exists(disk.device), disk
- else:
- # we cannot make any assumption about this, see:
- # http://goo.gl/p9c43
- disk.device
- if SUNOS or TRAVIS:
- # on solaris apparently mount points can also be files
- assert os.path.exists(disk.mountpoint), disk
- else:
- assert os.path.isdir(disk.mountpoint), disk
- assert disk.fstype, disk
-
- # all = True
- ls = psutil.disk_partitions(all=True)
- self.assertTrue(ls, msg=ls)
- for disk in psutil.disk_partitions(all=True):
- if not WINDOWS:
- try:
- os.stat(disk.mountpoint)
- except OSError as err:
- if TRAVIS and MACOS and err.errno == errno.EIO:
- continue
- # http://mail.python.org/pipermail/python-dev/
- # 2012-June/120787.html
- if err.errno not in (errno.EPERM, errno.EACCES):
- raise
- else:
- if SUNOS or TRAVIS:
- # on solaris apparently mount points can also be files
- assert os.path.exists(disk.mountpoint), disk
- else:
- assert os.path.isdir(disk.mountpoint), disk
- self.assertIsInstance(disk.fstype, str)
- self.assertIsInstance(disk.opts, str)
-
- def find_mount_point(path):
- path = os.path.abspath(path)
- while not os.path.ismount(path):
- path = os.path.dirname(path)
- return path.lower()
-
- mount = find_mount_point(__file__)
- mounts = [x.mountpoint.lower() for x in
- psutil.disk_partitions(all=True)]
- self.assertIn(mount, mounts)
- psutil.disk_usage(mount)
-
- def test_net_io_counters(self):
- def check_ntuple(nt):
- self.assertEqual(nt[0], nt.bytes_sent)
- self.assertEqual(nt[1], nt.bytes_recv)
- self.assertEqual(nt[2], nt.packets_sent)
- self.assertEqual(nt[3], nt.packets_recv)
- self.assertEqual(nt[4], nt.errin)
- self.assertEqual(nt[5], nt.errout)
- self.assertEqual(nt[6], nt.dropin)
- self.assertEqual(nt[7], nt.dropout)
- assert nt.bytes_sent >= 0, nt
- assert nt.bytes_recv >= 0, nt
- assert nt.packets_sent >= 0, nt
- assert nt.packets_recv >= 0, nt
- assert nt.errin >= 0, nt
- assert nt.errout >= 0, nt
- assert nt.dropin >= 0, nt
- assert nt.dropout >= 0, nt
-
- ret = psutil.net_io_counters(pernic=False)
- check_ntuple(ret)
- ret = psutil.net_io_counters(pernic=True)
- self.assertNotEqual(ret, [])
- for key in ret:
- self.assertTrue(key)
- self.assertIsInstance(key, str)
- check_ntuple(ret[key])
-
- def test_net_io_counters_no_nics(self):
- # Emulate a case where no NICs are installed, see:
- # https://github.com/giampaolo/psutil/issues/1062
- with mock.patch('psutil._psplatform.net_io_counters',
- return_value={}) as m:
- self.assertIsNone(psutil.net_io_counters(pernic=False))
- self.assertEqual(psutil.net_io_counters(pernic=True), {})
- assert m.called
-
- def test_net_if_addrs(self):
- nics = psutil.net_if_addrs()
- assert nics, nics
-
- nic_stats = psutil.net_if_stats()
-
- # Not reliable on all platforms (net_if_addrs() reports more
- # interfaces).
- # self.assertEqual(sorted(nics.keys()),
- # sorted(psutil.net_io_counters(pernic=True).keys()))
-
- families = set([socket.AF_INET, socket.AF_INET6, psutil.AF_LINK])
- for nic, addrs in nics.items():
- self.assertIsInstance(nic, str)
- self.assertEqual(len(set(addrs)), len(addrs))
- for addr in addrs:
- self.assertIsInstance(addr.family, int)
- self.assertIsInstance(addr.address, str)
- self.assertIsInstance(addr.netmask, (str, type(None)))
- self.assertIsInstance(addr.broadcast, (str, type(None)))
- self.assertIn(addr.family, families)
- if sys.version_info >= (3, 4):
- self.assertIsInstance(addr.family, enum.IntEnum)
- if nic_stats[nic].isup:
- # Do not test binding to addresses of interfaces
- # that are down
- if addr.family == socket.AF_INET:
- s = socket.socket(addr.family)
- with contextlib.closing(s):
- s.bind((addr.address, 0))
- elif addr.family == socket.AF_INET6:
- info = socket.getaddrinfo(
- addr.address, 0, socket.AF_INET6,
- socket.SOCK_STREAM, 0, socket.AI_PASSIVE)[0]
- af, socktype, proto, canonname, sa = info
- s = socket.socket(af, socktype, proto)
- with contextlib.closing(s):
- s.bind(sa)
- for ip in (addr.address, addr.netmask, addr.broadcast,
- addr.ptp):
- if ip is not None:
- # TODO: skip AF_INET6 for now because I get:
- # AddressValueError: Only hex digits permitted in
- # u'c6f3%lxcbr0' in u'fe80::c8e0:fff:fe54:c6f3%lxcbr0'
- if addr.family != socket.AF_INET6:
- check_net_address(ip, addr.family)
- # broadcast and ptp addresses are mutually exclusive
- if addr.broadcast:
- self.assertIsNone(addr.ptp)
- elif addr.ptp:
- self.assertIsNone(addr.broadcast)
-
- if BSD or MACOS or SUNOS:
- if hasattr(socket, "AF_LINK"):
- self.assertEqual(psutil.AF_LINK, socket.AF_LINK)
- elif LINUX:
- self.assertEqual(psutil.AF_LINK, socket.AF_PACKET)
- elif WINDOWS:
- self.assertEqual(psutil.AF_LINK, -1)
-
- def test_net_if_addrs_mac_null_bytes(self):
- # Simulate that the underlying C function returns an incomplete
- # MAC address. psutil is supposed to fill it with null bytes.
- # https://github.com/giampaolo/psutil/issues/786
- if POSIX:
- ret = [('em1', psutil.AF_LINK, '06:3d:29', None, None, None)]
- else:
- ret = [('em1', -1, '06-3d-29', None, None, None)]
- with mock.patch('psutil._psplatform.net_if_addrs',
- return_value=ret) as m:
- addr = psutil.net_if_addrs()['em1'][0]
- assert m.called
- if POSIX:
- self.assertEqual(addr.address, '06:3d:29:00:00:00')
- else:
- self.assertEqual(addr.address, '06-3d-29-00-00-00')
-
- @unittest.skipIf(TRAVIS, "unreliable on TRAVIS") # raises EPERM
- def test_net_if_stats(self):
- nics = psutil.net_if_stats()
- assert nics, nics
- all_duplexes = (psutil.NIC_DUPLEX_FULL,
- psutil.NIC_DUPLEX_HALF,
- psutil.NIC_DUPLEX_UNKNOWN)
- for name, stats in nics.items():
- self.assertIsInstance(name, str)
- isup, duplex, speed, mtu = stats
- self.assertIsInstance(isup, bool)
- self.assertIn(duplex, all_duplexes)
- self.assertIn(duplex, all_duplexes)
- self.assertGreaterEqual(speed, 0)
- self.assertGreaterEqual(mtu, 0)
-
- @unittest.skipIf(not (LINUX or BSD or MACOS),
- "LINUX or BSD or MACOS specific")
- def test_net_if_stats_enodev(self):
- # See: https://github.com/giampaolo/psutil/issues/1279
- with mock.patch('psutil._psutil_posix.net_if_mtu',
- side_effect=OSError(errno.ENODEV, "")) as m:
- ret = psutil.net_if_stats()
- self.assertEqual(ret, {})
- assert m.called
-
- @unittest.skipIf(LINUX and not os.path.exists('/proc/diskstats'),
- '/proc/diskstats not available on this linux version')
- @unittest.skipIf(APPVEYOR and psutil.disk_io_counters() is None,
- "unreliable on APPVEYOR") # no visible disks
- def test_disk_io_counters(self):
- def check_ntuple(nt):
- self.assertEqual(nt[0], nt.read_count)
- self.assertEqual(nt[1], nt.write_count)
- self.assertEqual(nt[2], nt.read_bytes)
- self.assertEqual(nt[3], nt.write_bytes)
- if not (OPENBSD or NETBSD):
- self.assertEqual(nt[4], nt.read_time)
- self.assertEqual(nt[5], nt.write_time)
- if LINUX:
- self.assertEqual(nt[6], nt.read_merged_count)
- self.assertEqual(nt[7], nt.write_merged_count)
- self.assertEqual(nt[8], nt.busy_time)
- elif FREEBSD:
- self.assertEqual(nt[6], nt.busy_time)
- for name in nt._fields:
- assert getattr(nt, name) >= 0, nt
-
- ret = psutil.disk_io_counters(perdisk=False)
- assert ret is not None, "no disks on this system?"
- check_ntuple(ret)
- ret = psutil.disk_io_counters(perdisk=True)
- # make sure there are no duplicates
- self.assertEqual(len(ret), len(set(ret)))
- for key in ret:
- assert key, key
- check_ntuple(ret[key])
-
- def test_disk_io_counters_no_disks(self):
- # Emulate a case where no disks are installed, see:
- # https://github.com/giampaolo/psutil/issues/1062
- with mock.patch('psutil._psplatform.disk_io_counters',
- return_value={}) as m:
- self.assertIsNone(psutil.disk_io_counters(perdisk=False))
- self.assertEqual(psutil.disk_io_counters(perdisk=True), {})
- assert m.called
-
- # can't find users on APPVEYOR or TRAVIS
- @unittest.skipIf(APPVEYOR or TRAVIS and not psutil.users(),
- "unreliable on APPVEYOR or TRAVIS")
- def test_users(self):
- users = psutil.users()
- self.assertNotEqual(users, [])
- for user in users:
- assert user.name, user
- self.assertIsInstance(user.name, str)
- self.assertIsInstance(user.terminal, (str, type(None)))
- if user.host is not None:
- self.assertIsInstance(user.host, (str, type(None)))
- user.terminal
- user.host
- assert user.started > 0.0, user
- datetime.datetime.fromtimestamp(user.started)
- if WINDOWS or OPENBSD:
- self.assertIsNone(user.pid)
- else:
- psutil.Process(user.pid)
-
- def test_cpu_stats(self):
- # Tested more extensively in per-platform test modules.
- infos = psutil.cpu_stats()
- self.assertEqual(
- infos._fields,
- ('ctx_switches', 'interrupts', 'soft_interrupts', 'syscalls'))
- for name in infos._fields:
- value = getattr(infos, name)
- self.assertGreaterEqual(value, 0)
- # on AIX, ctx_switches is always 0
- if not AIX and name in ('ctx_switches', 'interrupts'):
- self.assertGreater(value, 0)
-
- @unittest.skipIf(not HAS_CPU_FREQ, "not suported")
- def test_cpu_freq(self):
- def check_ls(ls):
- for nt in ls:
- self.assertEqual(nt._fields, ('current', 'min', 'max'))
- self.assertLessEqual(nt.current, nt.max)
- for name in nt._fields:
- value = getattr(nt, name)
- self.assertIsInstance(value, (int, long, float))
- self.assertGreaterEqual(value, 0)
-
- ls = psutil.cpu_freq(percpu=True)
- if TRAVIS and not ls:
- return
-
- assert ls, ls
- check_ls([psutil.cpu_freq(percpu=False)])
-
- if LINUX:
- self.assertEqual(len(ls), psutil.cpu_count())
-
- def test_os_constants(self):
- names = ["POSIX", "WINDOWS", "LINUX", "MACOS", "FREEBSD", "OPENBSD",
- "NETBSD", "BSD", "SUNOS"]
- for name in names:
- self.assertIsInstance(getattr(psutil, name), bool, msg=name)
-
- if os.name == 'posix':
- assert psutil.POSIX
- assert not psutil.WINDOWS
- names.remove("POSIX")
- if "linux" in sys.platform.lower():
- assert psutil.LINUX
- names.remove("LINUX")
- elif "bsd" in sys.platform.lower():
- assert psutil.BSD
- self.assertEqual([psutil.FREEBSD, psutil.OPENBSD,
- psutil.NETBSD].count(True), 1)
- names.remove("BSD")
- names.remove("FREEBSD")
- names.remove("OPENBSD")
- names.remove("NETBSD")
- elif "sunos" in sys.platform.lower() or \
- "solaris" in sys.platform.lower():
- assert psutil.SUNOS
- names.remove("SUNOS")
- elif "darwin" in sys.platform.lower():
- assert psutil.MACOS
- names.remove("MACOS")
- else:
- assert psutil.WINDOWS
- assert not psutil.POSIX
- names.remove("WINDOWS")
-
- # assert all other constants are set to False
- for name in names:
- self.assertIs(getattr(psutil, name), False, msg=name)
-
- @unittest.skipIf(not HAS_SENSORS_TEMPERATURES, "not supported")
- def test_sensors_temperatures(self):
- temps = psutil.sensors_temperatures()
- for name, entries in temps.items():
- self.assertIsInstance(name, str)
- for entry in entries:
- self.assertIsInstance(entry.label, str)
- if entry.current is not None:
- self.assertGreaterEqual(entry.current, 0)
- if entry.high is not None:
- self.assertGreaterEqual(entry.high, 0)
- if entry.critical is not None:
- self.assertGreaterEqual(entry.critical, 0)
-
- @unittest.skipIf(not HAS_SENSORS_TEMPERATURES, "not supported")
- def test_sensors_temperatures_fahreneit(self):
- d = {'coretemp': [('label', 50.0, 60.0, 70.0)]}
- with mock.patch("psutil._psplatform.sensors_temperatures",
- return_value=d) as m:
- temps = psutil.sensors_temperatures(
- fahrenheit=True)['coretemp'][0]
- assert m.called
- self.assertEqual(temps.current, 122.0)
- self.assertEqual(temps.high, 140.0)
- self.assertEqual(temps.critical, 158.0)
-
- @unittest.skipIf(not HAS_SENSORS_BATTERY, "not supported")
- @unittest.skipIf(not HAS_BATTERY, "no battery")
- def test_sensors_battery(self):
- ret = psutil.sensors_battery()
- self.assertGreaterEqual(ret.percent, 0)
- self.assertLessEqual(ret.percent, 100)
- if ret.secsleft not in (psutil.POWER_TIME_UNKNOWN,
- psutil.POWER_TIME_UNLIMITED):
- self.assertGreaterEqual(ret.secsleft, 0)
- else:
- if ret.secsleft == psutil.POWER_TIME_UNLIMITED:
- self.assertTrue(ret.power_plugged)
- self.assertIsInstance(ret.power_plugged, bool)
-
- @unittest.skipIf(not HAS_SENSORS_FANS, "not supported")
- def test_sensors_fans(self):
- fans = psutil.sensors_fans()
- for name, entries in fans.items():
- self.assertIsInstance(name, str)
- for entry in entries:
- self.assertIsInstance(entry.label, str)
- self.assertIsInstance(entry.current, (int, long))
- self.assertGreaterEqual(entry.current, 0)
-
-
-if __name__ == '__main__':
- run_test_module_by_name(__file__)
diff --git a/server/www/packages/packages-darwin/x64/psutil/tests/test_unicode.py b/server/www/packages/packages-darwin/x64/psutil/tests/test_unicode.py
deleted file mode 100644
index 4144b5c..0000000
--- a/server/www/packages/packages-darwin/x64/psutil/tests/test_unicode.py
+++ /dev/null
@@ -1,366 +0,0 @@
-#!/usr/bin/env python
-# -*- 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.
-
-"""
-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
-"""
-
-import os
-import traceback
-import warnings
-from contextlib import closing
-
-from psutil import BSD
-from psutil import MACOS
-from psutil import OPENBSD
-from psutil import POSIX
-from psutil import WINDOWS
-from psutil._compat import PY3
-from psutil._compat import u
-from psutil.tests import APPVEYOR
-from psutil.tests import ASCII_FS
-from psutil.tests import bind_unix_socket
-from psutil.tests import chdir
-from psutil.tests import copyload_shared_lib
-from psutil.tests import create_exe
-from psutil.tests import get_test_subprocess
-from psutil.tests import HAS_CONNECTIONS_UNIX
-from psutil.tests import HAS_ENVIRON
-from psutil.tests import HAS_MEMORY_MAPS
-from psutil.tests import mock
-from psutil.tests import reap_children
-from psutil.tests import run_test_module_by_name
-from psutil.tests import safe_mkdir
-from psutil.tests import safe_rmpath as _safe_rmpath
-from psutil.tests import skip_on_access_denied
-from psutil.tests import TESTFILE_PREFIX
-from psutil.tests import TESTFN
-from psutil.tests import TESTFN_UNICODE
-from psutil.tests import TRAVIS
-from psutil.tests import unittest
-from psutil.tests import unix_socket_path
-import psutil
-
-
-def safe_rmpath(path):
- if APPVEYOR:
- # TODO - this is quite random and I'm not sure why it happens,
- # nor I can reproduce it locally:
- # https://ci.appveyor.com/project/giampaolo/psutil/build/job/
- # jiq2cgd6stsbtn60
- # safe_rmpath() happens after reap_children() so this is weird
- # Perhaps wait_procs() on Windows is broken? Maybe because
- # of STILL_ACTIVE?
- # https://github.com/giampaolo/psutil/blob/
- # 68c7a70728a31d8b8b58f4be6c4c0baa2f449eda/psutil/arch/
- # windows/process_info.c#L146
- try:
- return _safe_rmpath(path)
- except WindowsError:
- traceback.print_exc()
- else:
- return _safe_rmpath(path)
-
-
-def subprocess_supports_unicode(name):
- """Return True if both the fs and the subprocess module can
- deal with a unicode file name.
- """
- if PY3:
- return True
- try:
- safe_rmpath(name)
- create_exe(name)
- get_test_subprocess(cmd=[name])
- except UnicodeEncodeError:
- return False
- else:
- return True
- finally:
- reap_children()
-
-
-# An invalid unicode string.
-if PY3:
- INVALID_NAME = (TESTFN.encode('utf8') + b"f\xc0\x80").decode(
- 'utf8', 'surrogateescape')
-else:
- INVALID_NAME = TESTFN + "f\xc0\x80"
-
-
-# ===================================================================
-# FS APIs
-# ===================================================================
-
-
-class _BaseFSAPIsTests(object):
- funky_name = None
-
- @classmethod
- def setUpClass(cls):
- safe_rmpath(cls.funky_name)
- create_exe(cls.funky_name)
-
- @classmethod
- def tearDownClass(cls):
- reap_children()
- safe_rmpath(cls.funky_name)
-
- def tearDown(self):
- reap_children()
-
- def expect_exact_path_match(self):
- raise NotImplementedError("must be implemented in subclass")
-
- def test_proc_exe(self):
- subp = get_test_subprocess(cmd=[self.funky_name])
- p = psutil.Process(subp.pid)
- exe = p.exe()
- self.assertIsInstance(exe, str)
- if self.expect_exact_path_match():
- self.assertEqual(exe, self.funky_name)
-
- def test_proc_name(self):
- subp = get_test_subprocess(cmd=[self.funky_name])
- if WINDOWS:
- # On Windows name() is determined from exe() first, because
- # it's faster; we want to overcome the internal optimization
- # and test name() instead of exe().
- with mock.patch("psutil._psplatform.cext.proc_exe",
- side_effect=psutil.AccessDenied(os.getpid())) as m:
- name = psutil.Process(subp.pid).name()
- assert m.called
- else:
- name = psutil.Process(subp.pid).name()
- self.assertIsInstance(name, str)
- if self.expect_exact_path_match():
- self.assertEqual(name, os.path.basename(self.funky_name))
-
- def test_proc_cmdline(self):
- subp = get_test_subprocess(cmd=[self.funky_name])
- p = psutil.Process(subp.pid)
- cmdline = p.cmdline()
- for part in cmdline:
- self.assertIsInstance(part, str)
- if self.expect_exact_path_match():
- self.assertEqual(cmdline, [self.funky_name])
-
- def test_proc_cwd(self):
- dname = self.funky_name + "2"
- self.addCleanup(safe_rmpath, dname)
- safe_mkdir(dname)
- with chdir(dname):
- p = psutil.Process()
- cwd = p.cwd()
- self.assertIsInstance(p.cwd(), str)
- if self.expect_exact_path_match():
- self.assertEqual(cwd, dname)
-
- def test_proc_open_files(self):
- p = psutil.Process()
- start = set(p.open_files())
- with open(self.funky_name, 'rb'):
- new = set(p.open_files())
- path = (new - start).pop().path
- self.assertIsInstance(path, str)
- if BSD and not path:
- # XXX - see https://github.com/giampaolo/psutil/issues/595
- return self.skipTest("open_files on BSD is broken")
- if self.expect_exact_path_match():
- self.assertEqual(os.path.normcase(path),
- os.path.normcase(self.funky_name))
-
- @unittest.skipIf(not POSIX, "POSIX only")
- def test_proc_connections(self):
- suffix = os.path.basename(self.funky_name)
- with unix_socket_path(suffix=suffix) as name:
- try:
- sock = bind_unix_socket(name)
- except UnicodeEncodeError:
- if PY3:
- raise
- else:
- raise unittest.SkipTest("not supported")
- with closing(sock):
- conn = psutil.Process().connections('unix')[0]
- self.assertIsInstance(conn.laddr, str)
- # AF_UNIX addr not set on OpenBSD
- if not OPENBSD:
- self.assertEqual(conn.laddr, name)
-
- @unittest.skipIf(not POSIX, "POSIX only")
- @unittest.skipIf(not HAS_CONNECTIONS_UNIX, "can't list UNIX sockets")
- @skip_on_access_denied()
- def test_net_connections(self):
- def find_sock(cons):
- for conn in cons:
- if os.path.basename(conn.laddr).startswith(TESTFILE_PREFIX):
- return conn
- raise ValueError("connection not found")
-
- suffix = os.path.basename(self.funky_name)
- with unix_socket_path(suffix=suffix) as name:
- try:
- sock = bind_unix_socket(name)
- except UnicodeEncodeError:
- if PY3:
- raise
- else:
- raise unittest.SkipTest("not supported")
- with closing(sock):
- cons = psutil.net_connections(kind='unix')
- # AF_UNIX addr not set on OpenBSD
- if not OPENBSD:
- conn = find_sock(cons)
- self.assertIsInstance(conn.laddr, str)
- self.assertEqual(conn.laddr, name)
-
- def test_disk_usage(self):
- dname = self.funky_name + "2"
- self.addCleanup(safe_rmpath, dname)
- safe_mkdir(dname)
- psutil.disk_usage(dname)
-
- @unittest.skipIf(not HAS_MEMORY_MAPS, "not supported")
- @unittest.skipIf(not PY3, "ctypes does not support unicode on PY2")
- def test_memory_maps(self):
- # XXX: on Python 2, using ctypes.CDLL with a unicode path
- # opens a message box which blocks the test run.
- with copyload_shared_lib(dst_prefix=self.funky_name) as funky_path:
- def normpath(p):
- return os.path.realpath(os.path.normcase(p))
- libpaths = [normpath(x.path)
- for x in psutil.Process().memory_maps()]
- # ...just to have a clearer msg in case of failure
- libpaths = [x for x in libpaths if TESTFILE_PREFIX in x]
- self.assertIn(normpath(funky_path), libpaths)
- for path in libpaths:
- self.assertIsInstance(path, str)
-
-
-@unittest.skipIf(MACOS and TRAVIS, "unreliable on TRAVIS") # TODO
-@unittest.skipIf(ASCII_FS, "ASCII fs")
-@unittest.skipIf(not subprocess_supports_unicode(TESTFN_UNICODE),
- "subprocess can't deal with unicode")
-class TestFSAPIs(_BaseFSAPIsTests, unittest.TestCase):
- """Test FS APIs with a funky, valid, UTF8 path name."""
- funky_name = TESTFN_UNICODE
-
- @classmethod
- def expect_exact_path_match(cls):
- # Do not expect psutil to correctly handle unicode paths on
- # Python 2 if os.listdir() is not able either.
- if PY3:
- return True
- else:
- here = '.' if isinstance(cls.funky_name, str) else u('.')
- with warnings.catch_warnings():
- warnings.simplefilter("ignore")
- return cls.funky_name in os.listdir(here)
-
-
-@unittest.skipIf(MACOS and TRAVIS, "unreliable on TRAVIS") # TODO
-@unittest.skipIf(not subprocess_supports_unicode(INVALID_NAME),
- "subprocess can't deal with invalid unicode")
-class TestFSAPIsWithInvalidPath(_BaseFSAPIsTests, unittest.TestCase):
- """Test FS APIs with a funky, invalid path name."""
- funky_name = INVALID_NAME
-
- @classmethod
- def expect_exact_path_match(cls):
- # Invalid unicode names are supposed to work on Python 2.
- return True
-
-
-@unittest.skipIf(not WINDOWS, "WINDOWS only")
-class TestWinProcessName(unittest.TestCase):
-
- def test_name_type(self):
- # On Windows name() is determined from exe() first, because
- # it's faster; we want to overcome the internal optimization
- # and test name() instead of exe().
- with mock.patch("psutil._psplatform.cext.proc_exe",
- side_effect=psutil.AccessDenied(os.getpid())) as m:
- self.assertIsInstance(psutil.Process().name(), str)
- assert m.called
-
-
-# ===================================================================
-# Non fs APIs
-# ===================================================================
-
-
-class TestNonFSAPIS(unittest.TestCase):
- """Unicode tests for non fs-related APIs."""
-
- def tearDown(self):
- reap_children()
-
- @unittest.skipIf(not HAS_ENVIRON, "not supported")
- def test_proc_environ(self):
- # Note: differently from others, this test does not deal
- # with fs paths. On Python 2 subprocess module is broken as
- # it's not able to handle with non-ASCII env vars, so
- # we use "è", which is part of the extended ASCII table
- # (unicode point <= 255).
- env = os.environ.copy()
- funky_str = TESTFN_UNICODE if PY3 else 'è'
- env['FUNNY_ARG'] = funky_str
- sproc = get_test_subprocess(env=env)
- p = psutil.Process(sproc.pid)
- env = p.environ()
- for k, v in env.items():
- self.assertIsInstance(k, str)
- self.assertIsInstance(v, str)
- self.assertEqual(env['FUNNY_ARG'], funky_str)
-
-
-if __name__ == '__main__':
- run_test_module_by_name(__file__)
diff --git a/server/www/packages/packages-darwin/x64/psutil/tests/test_windows.py b/server/www/packages/packages-darwin/x64/psutil/tests/test_windows.py
deleted file mode 100644
index ffa763d..0000000
--- a/server/www/packages/packages-darwin/x64/psutil/tests/test_windows.py
+++ /dev/null
@@ -1,859 +0,0 @@
-#!/usr/bin/env python
-# -*- 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.
-
-"""Windows specific tests."""
-
-import datetime
-import errno
-import glob
-import os
-import platform
-import re
-import signal
-import subprocess
-import sys
-import time
-import warnings
-
-import psutil
-from psutil import WINDOWS
-from psutil.tests import APPVEYOR
-from psutil.tests import get_test_subprocess
-from psutil.tests import HAS_BATTERY
-from psutil.tests import mock
-from psutil.tests import reap_children
-from psutil.tests import retry_before_failing
-from psutil.tests import run_test_module_by_name
-from psutil.tests import sh
-from psutil.tests import unittest
-
-with warnings.catch_warnings():
- warnings.simplefilter("ignore")
- try:
- import win32api # requires "pip install pypiwin32"
- import win32con
- import win32process
- import wmi # requires "pip install wmi" / "make setup-dev-env"
- except ImportError:
- if os.name == 'nt':
- raise
-
-
-cext = psutil._psplatform.cext
-
-# are we a 64 bit process
-IS_64_BIT = sys.maxsize > 2**32
-
-
-def wrap_exceptions(fun):
- def wrapper(self, *args, **kwargs):
- try:
- return fun(self, *args, **kwargs)
- except OSError as err:
- from psutil._pswindows import ACCESS_DENIED_SET
- if err.errno in ACCESS_DENIED_SET:
- raise psutil.AccessDenied(None, None)
- if err.errno == errno.ESRCH:
- raise psutil.NoSuchProcess(None, None)
- raise
- return wrapper
-
-
-# ===================================================================
-# System APIs
-# ===================================================================
-
-
-@unittest.skipIf(not WINDOWS, "WINDOWS only")
-class TestCpuAPIs(unittest.TestCase):
-
- @unittest.skipIf('NUMBER_OF_PROCESSORS' not in os.environ,
- 'NUMBER_OF_PROCESSORS env var is not available')
- def test_cpu_count_vs_NUMBER_OF_PROCESSORS(self):
- # Will likely fail on many-cores systems:
- # https://stackoverflow.com/questions/31209256
- num_cpus = int(os.environ['NUMBER_OF_PROCESSORS'])
- self.assertEqual(num_cpus, psutil.cpu_count())
-
- def test_cpu_count_vs_GetSystemInfo(self):
- # Will likely fail on many-cores systems:
- # https://stackoverflow.com/questions/31209256
- sys_value = win32api.GetSystemInfo()[5]
- psutil_value = psutil.cpu_count()
- self.assertEqual(sys_value, psutil_value)
-
- def test_cpu_count_logical_vs_wmi(self):
- w = wmi.WMI()
- proc = w.Win32_Processor()[0]
- self.assertEqual(psutil.cpu_count(), proc.NumberOfLogicalProcessors)
-
- def test_cpu_count_phys_vs_wmi(self):
- w = wmi.WMI()
- proc = w.Win32_Processor()[0]
- self.assertEqual(psutil.cpu_count(logical=False), proc.NumberOfCores)
-
- def test_cpu_count_vs_cpu_times(self):
- self.assertEqual(psutil.cpu_count(),
- len(psutil.cpu_times(percpu=True)))
-
- def test_cpu_freq(self):
- w = wmi.WMI()
- proc = w.Win32_Processor()[0]
- self.assertEqual(proc.CurrentClockSpeed, psutil.cpu_freq().current)
- self.assertEqual(proc.MaxClockSpeed, psutil.cpu_freq().max)
-
-
-@unittest.skipIf(not WINDOWS, "WINDOWS only")
-class TestSystemAPIs(unittest.TestCase):
-
- def test_nic_names(self):
- out = sh('ipconfig /all')
- nics = psutil.net_io_counters(pernic=True).keys()
- for nic in nics:
- if "pseudo-interface" in nic.replace(' ', '-').lower():
- continue
- if nic not in out:
- self.fail(
- "%r nic wasn't found in 'ipconfig /all' output" % nic)
-
- def test_total_phymem(self):
- w = wmi.WMI().Win32_ComputerSystem()[0]
- self.assertEqual(int(w.TotalPhysicalMemory),
- psutil.virtual_memory().total)
-
- # @unittest.skipIf(wmi is None, "wmi module is not installed")
- # def test__UPTIME(self):
- # # _UPTIME constant is not public but it is used internally
- # # as value to return for pid 0 creation time.
- # # WMI behaves the same.
- # w = wmi.WMI().Win32_Process(ProcessId=self.pid)[0]
- # p = psutil.Process(0)
- # wmic_create = str(w.CreationDate.split('.')[0])
- # psutil_create = time.strftime("%Y%m%d%H%M%S",
- # time.localtime(p.create_time()))
-
- # Note: this test is not very reliable
- @unittest.skipIf(APPVEYOR, "test not relieable on appveyor")
- @retry_before_failing()
- def test_pids(self):
- # Note: this test might fail if the OS is starting/killing
- # other processes in the meantime
- w = wmi.WMI().Win32_Process()
- wmi_pids = set([x.ProcessId for x in w])
- psutil_pids = set(psutil.pids())
- self.assertEqual(wmi_pids, psutil_pids)
-
- @retry_before_failing()
- def test_disks(self):
- ps_parts = psutil.disk_partitions(all=True)
- wmi_parts = wmi.WMI().Win32_LogicalDisk()
- for ps_part in ps_parts:
- for wmi_part in wmi_parts:
- if ps_part.device.replace('\\', '') == wmi_part.DeviceID:
- if not ps_part.mountpoint:
- # this is usually a CD-ROM with no disk inserted
- break
- try:
- usage = psutil.disk_usage(ps_part.mountpoint)
- except OSError as err:
- if err.errno == errno.ENOENT:
- # usually this is the floppy
- break
- else:
- raise
- self.assertEqual(usage.total, int(wmi_part.Size))
- wmi_free = int(wmi_part.FreeSpace)
- self.assertEqual(usage.free, wmi_free)
- # 10 MB tollerance
- if abs(usage.free - wmi_free) > 10 * 1024 * 1024:
- self.fail("psutil=%s, wmi=%s" % (
- usage.free, wmi_free))
- break
- else:
- self.fail("can't find partition %s" % repr(ps_part))
-
- def test_disk_usage(self):
- for disk in psutil.disk_partitions():
- sys_value = win32api.GetDiskFreeSpaceEx(disk.mountpoint)
- psutil_value = psutil.disk_usage(disk.mountpoint)
- self.assertAlmostEqual(sys_value[0], psutil_value.free,
- delta=1024 * 1024)
- self.assertAlmostEqual(sys_value[1], psutil_value.total,
- delta=1024 * 1024)
- self.assertEqual(psutil_value.used,
- psutil_value.total - psutil_value.free)
-
- def test_disk_partitions(self):
- sys_value = [
- x + '\\' for x in win32api.GetLogicalDriveStrings().split("\\\x00")
- if x and not x.startswith('A:')]
- psutil_value = [x.mountpoint for x in psutil.disk_partitions(all=True)]
- self.assertEqual(sys_value, psutil_value)
-
- def test_net_if_stats(self):
- ps_names = set(cext.net_if_stats())
- wmi_adapters = wmi.WMI().Win32_NetworkAdapter()
- wmi_names = set()
- for wmi_adapter in wmi_adapters:
- wmi_names.add(wmi_adapter.Name)
- wmi_names.add(wmi_adapter.NetConnectionID)
- self.assertTrue(ps_names & wmi_names,
- "no common entries in %s, %s" % (ps_names, wmi_names))
-
- def test_boot_time(self):
- wmi_os = wmi.WMI().Win32_OperatingSystem()
- wmi_btime_str = wmi_os[0].LastBootUpTime.split('.')[0]
- wmi_btime_dt = datetime.datetime.strptime(
- wmi_btime_str, "%Y%m%d%H%M%S")
- psutil_dt = datetime.datetime.fromtimestamp(psutil.boot_time())
- diff = abs((wmi_btime_dt - psutil_dt).total_seconds())
- # Wmic time is 2-3 secs lower for some reason; that's OK.
- self.assertLessEqual(diff, 3)
-
- def test_boot_time_fluctuation(self):
- # https://github.com/giampaolo/psutil/issues/1007
- with mock.patch('psutil._pswindows.cext.boot_time', return_value=5):
- self.assertEqual(psutil.boot_time(), 5)
- with mock.patch('psutil._pswindows.cext.boot_time', return_value=4):
- self.assertEqual(psutil.boot_time(), 5)
- with mock.patch('psutil._pswindows.cext.boot_time', return_value=6):
- self.assertEqual(psutil.boot_time(), 5)
- with mock.patch('psutil._pswindows.cext.boot_time', return_value=333):
- self.assertEqual(psutil.boot_time(), 333)
-
-
-# ===================================================================
-# sensors_battery()
-# ===================================================================
-
-
-@unittest.skipIf(not WINDOWS, "WINDOWS only")
-class TestSensorsBattery(unittest.TestCase):
-
- def test_has_battery(self):
- if win32api.GetPwrCapabilities()['SystemBatteriesPresent']:
- self.assertIsNotNone(psutil.sensors_battery())
- else:
- self.assertIsNone(psutil.sensors_battery())
-
- @unittest.skipIf(not HAS_BATTERY, "no battery")
- def test_percent(self):
- w = wmi.WMI()
- battery_wmi = w.query('select * from Win32_Battery')[0]
- battery_psutil = psutil.sensors_battery()
- self.assertAlmostEqual(
- battery_psutil.percent, battery_wmi.EstimatedChargeRemaining,
- delta=1)
-
- @unittest.skipIf(not HAS_BATTERY, "no battery")
- def test_power_plugged(self):
- w = wmi.WMI()
- battery_wmi = w.query('select * from Win32_Battery')[0]
- battery_psutil = psutil.sensors_battery()
- # Status codes:
- # https://msdn.microsoft.com/en-us/library/aa394074(v=vs.85).aspx
- self.assertEqual(battery_psutil.power_plugged,
- battery_wmi.BatteryStatus == 2)
-
- def test_emulate_no_battery(self):
- with mock.patch("psutil._pswindows.cext.sensors_battery",
- return_value=(0, 128, 0, 0)) as m:
- self.assertIsNone(psutil.sensors_battery())
- assert m.called
-
- def test_emulate_power_connected(self):
- with mock.patch("psutil._pswindows.cext.sensors_battery",
- return_value=(1, 0, 0, 0)) as m:
- self.assertEqual(psutil.sensors_battery().secsleft,
- psutil.POWER_TIME_UNLIMITED)
- assert m.called
-
- def test_emulate_power_charging(self):
- with mock.patch("psutil._pswindows.cext.sensors_battery",
- return_value=(0, 8, 0, 0)) as m:
- self.assertEqual(psutil.sensors_battery().secsleft,
- psutil.POWER_TIME_UNLIMITED)
- assert m.called
-
- def test_emulate_secs_left_unknown(self):
- with mock.patch("psutil._pswindows.cext.sensors_battery",
- return_value=(0, 0, 0, -1)) as m:
- self.assertEqual(psutil.sensors_battery().secsleft,
- psutil.POWER_TIME_UNKNOWN)
- assert m.called
-
-
-# ===================================================================
-# Process APIs
-# ===================================================================
-
-
-@unittest.skipIf(not WINDOWS, "WINDOWS only")
-class TestProcess(unittest.TestCase):
-
- @classmethod
- def setUpClass(cls):
- cls.pid = get_test_subprocess().pid
-
- @classmethod
- def tearDownClass(cls):
- reap_children()
-
- def test_issue_24(self):
- p = psutil.Process(0)
- self.assertRaises(psutil.AccessDenied, p.kill)
-
- def test_special_pid(self):
- p = psutil.Process(4)
- self.assertEqual(p.name(), 'System')
- # use __str__ to access all common Process properties to check
- # that nothing strange happens
- str(p)
- p.username()
- self.assertTrue(p.create_time() >= 0.0)
- try:
- rss, vms = p.memory_info()[:2]
- except psutil.AccessDenied:
- # expected on Windows Vista and Windows 7
- if not platform.uname()[1] in ('vista', 'win-7', 'win7'):
- raise
- else:
- self.assertTrue(rss > 0)
-
- def test_send_signal(self):
- p = psutil.Process(self.pid)
- self.assertRaises(ValueError, p.send_signal, signal.SIGINT)
-
- def test_exe(self):
- for p in psutil.process_iter():
- try:
- self.assertEqual(os.path.basename(p.exe()), p.name())
- except psutil.Error:
- pass
-
- def test_num_handles_increment(self):
- p = psutil.Process(os.getpid())
- before = p.num_handles()
- handle = win32api.OpenProcess(win32con.PROCESS_QUERY_INFORMATION,
- win32con.FALSE, os.getpid())
- after = p.num_handles()
- self.assertEqual(after, before + 1)
- win32api.CloseHandle(handle)
- self.assertEqual(p.num_handles(), before)
-
- def test_handles_leak(self):
- # Call all Process methods and make sure no handles are left
- # open. This is here mainly to make sure functions using
- # OpenProcess() always call CloseHandle().
- def call(p, attr):
- attr = getattr(p, name, None)
- if attr is not None and callable(attr):
- attr()
- else:
- attr
-
- p = psutil.Process(self.pid)
- failures = []
- for name in dir(psutil.Process):
- if name.startswith('_') \
- or name in ('terminate', 'kill', 'suspend', 'resume',
- 'nice', 'send_signal', 'wait', 'children',
- 'as_dict', 'memory_info_ex'):
- continue
- else:
- try:
- call(p, name)
- num1 = p.num_handles()
- call(p, name)
- num2 = p.num_handles()
- except (psutil.NoSuchProcess, psutil.AccessDenied):
- pass
- else:
- if num2 > num1:
- fail = \
- "failure while processing Process.%s method " \
- "(before=%s, after=%s)" % (name, num1, num2)
- failures.append(fail)
- if failures:
- self.fail('\n' + '\n'.join(failures))
-
- def test_name_always_available(self):
- # On Windows name() is never supposed to raise AccessDenied,
- # see https://github.com/giampaolo/psutil/issues/627
- for p in psutil.process_iter():
- try:
- p.name()
- except psutil.NoSuchProcess:
- pass
-
- @unittest.skipIf(not sys.version_info >= (2, 7),
- "CTRL_* signals not supported")
- def test_ctrl_signals(self):
- p = psutil.Process(get_test_subprocess().pid)
- p.send_signal(signal.CTRL_C_EVENT)
- p.send_signal(signal.CTRL_BREAK_EVENT)
- p.kill()
- p.wait()
- self.assertRaises(psutil.NoSuchProcess,
- p.send_signal, signal.CTRL_C_EVENT)
- self.assertRaises(psutil.NoSuchProcess,
- p.send_signal, signal.CTRL_BREAK_EVENT)
-
- def test_compare_name_exe(self):
- for p in psutil.process_iter():
- try:
- a = os.path.basename(p.exe())
- b = p.name()
- except (psutil.NoSuchProcess, psutil.AccessDenied):
- pass
- else:
- self.assertEqual(a, b)
-
- def test_username(self):
- self.assertEqual(psutil.Process().username(),
- win32api.GetUserNameEx(win32con.NameSamCompatible))
-
- def test_cmdline(self):
- sys_value = re.sub(' +', ' ', win32api.GetCommandLine()).strip()
- psutil_value = ' '.join(psutil.Process().cmdline())
- self.assertEqual(sys_value, psutil_value)
-
- # XXX - occasional failures
-
- # def test_cpu_times(self):
- # handle = win32api.OpenProcess(win32con.PROCESS_QUERY_INFORMATION,
- # win32con.FALSE, os.getpid())
- # self.addCleanup(win32api.CloseHandle, handle)
- # sys_value = win32process.GetProcessTimes(handle)
- # psutil_value = psutil.Process().cpu_times()
- # self.assertAlmostEqual(
- # psutil_value.user, sys_value['UserTime'] / 10000000.0,
- # delta=0.2)
- # self.assertAlmostEqual(
- # psutil_value.user, sys_value['KernelTime'] / 10000000.0,
- # delta=0.2)
-
- def test_nice(self):
- handle = win32api.OpenProcess(win32con.PROCESS_QUERY_INFORMATION,
- win32con.FALSE, os.getpid())
- self.addCleanup(win32api.CloseHandle, handle)
- sys_value = win32process.GetPriorityClass(handle)
- psutil_value = psutil.Process().nice()
- self.assertEqual(psutil_value, sys_value)
-
- def test_memory_info(self):
- handle = win32api.OpenProcess(win32con.PROCESS_QUERY_INFORMATION,
- win32con.FALSE, self.pid)
- self.addCleanup(win32api.CloseHandle, handle)
- sys_value = win32process.GetProcessMemoryInfo(handle)
- psutil_value = psutil.Process(self.pid).memory_info()
- self.assertEqual(
- sys_value['PeakWorkingSetSize'], psutil_value.peak_wset)
- self.assertEqual(
- sys_value['WorkingSetSize'], psutil_value.wset)
- self.assertEqual(
- sys_value['QuotaPeakPagedPoolUsage'], psutil_value.peak_paged_pool)
- self.assertEqual(
- sys_value['QuotaPagedPoolUsage'], psutil_value.paged_pool)
- self.assertEqual(
- sys_value['QuotaPeakNonPagedPoolUsage'],
- psutil_value.peak_nonpaged_pool)
- self.assertEqual(
- sys_value['QuotaNonPagedPoolUsage'], psutil_value.nonpaged_pool)
- self.assertEqual(
- sys_value['PagefileUsage'], psutil_value.pagefile)
- self.assertEqual(
- sys_value['PeakPagefileUsage'], psutil_value.peak_pagefile)
-
- self.assertEqual(psutil_value.rss, psutil_value.wset)
- self.assertEqual(psutil_value.vms, psutil_value.pagefile)
-
- def test_wait(self):
- handle = win32api.OpenProcess(win32con.PROCESS_QUERY_INFORMATION,
- win32con.FALSE, self.pid)
- self.addCleanup(win32api.CloseHandle, handle)
- p = psutil.Process(self.pid)
- p.terminate()
- psutil_value = p.wait()
- sys_value = win32process.GetExitCodeProcess(handle)
- self.assertEqual(psutil_value, sys_value)
-
- def test_cpu_affinity(self):
- def from_bitmask(x):
- return [i for i in range(64) if (1 << i) & x]
-
- handle = win32api.OpenProcess(win32con.PROCESS_QUERY_INFORMATION,
- win32con.FALSE, self.pid)
- self.addCleanup(win32api.CloseHandle, handle)
- sys_value = from_bitmask(
- win32process.GetProcessAffinityMask(handle)[0])
- psutil_value = psutil.Process(self.pid).cpu_affinity()
- self.assertEqual(psutil_value, sys_value)
-
- def test_io_counters(self):
- handle = win32api.OpenProcess(win32con.PROCESS_QUERY_INFORMATION,
- win32con.FALSE, os.getpid())
- self.addCleanup(win32api.CloseHandle, handle)
- sys_value = win32process.GetProcessIoCounters(handle)
- psutil_value = psutil.Process().io_counters()
- self.assertEqual(
- psutil_value.read_count, sys_value['ReadOperationCount'])
- self.assertEqual(
- psutil_value.write_count, sys_value['WriteOperationCount'])
- self.assertEqual(
- psutil_value.read_bytes, sys_value['ReadTransferCount'])
- self.assertEqual(
- psutil_value.write_bytes, sys_value['WriteTransferCount'])
- self.assertEqual(
- psutil_value.other_count, sys_value['OtherOperationCount'])
- self.assertEqual(
- psutil_value.other_bytes, sys_value['OtherTransferCount'])
-
- def test_num_handles(self):
- import ctypes
- import ctypes.wintypes
- PROCESS_QUERY_INFORMATION = 0x400
- handle = ctypes.windll.kernel32.OpenProcess(
- PROCESS_QUERY_INFORMATION, 0, os.getpid())
- self.addCleanup(ctypes.windll.kernel32.CloseHandle, handle)
- hndcnt = ctypes.wintypes.DWORD()
- ctypes.windll.kernel32.GetProcessHandleCount(
- handle, ctypes.byref(hndcnt))
- sys_value = hndcnt.value
- psutil_value = psutil.Process().num_handles()
- ctypes.windll.kernel32.CloseHandle(handle)
- self.assertEqual(psutil_value, sys_value + 1)
-
-
-@unittest.skipIf(not WINDOWS, "WINDOWS only")
-class TestProcessWMI(unittest.TestCase):
- """Compare Process API results with WMI."""
-
- @classmethod
- def setUpClass(cls):
- cls.pid = get_test_subprocess().pid
-
- @classmethod
- def tearDownClass(cls):
- reap_children()
-
- def test_name(self):
- w = wmi.WMI().Win32_Process(ProcessId=self.pid)[0]
- p = psutil.Process(self.pid)
- self.assertEqual(p.name(), w.Caption)
-
- def test_exe(self):
- w = wmi.WMI().Win32_Process(ProcessId=self.pid)[0]
- p = psutil.Process(self.pid)
- # Note: wmi reports the exe as a lower case string.
- # Being Windows paths case-insensitive we ignore that.
- self.assertEqual(p.exe().lower(), w.ExecutablePath.lower())
-
- def test_cmdline(self):
- w = wmi.WMI().Win32_Process(ProcessId=self.pid)[0]
- p = psutil.Process(self.pid)
- self.assertEqual(' '.join(p.cmdline()),
- w.CommandLine.replace('"', ''))
-
- def test_username(self):
- w = wmi.WMI().Win32_Process(ProcessId=self.pid)[0]
- p = psutil.Process(self.pid)
- domain, _, username = w.GetOwner()
- username = "%s\\%s" % (domain, username)
- self.assertEqual(p.username(), username)
-
- def test_memory_rss(self):
- time.sleep(0.1)
- w = wmi.WMI().Win32_Process(ProcessId=self.pid)[0]
- p = psutil.Process(self.pid)
- rss = p.memory_info().rss
- self.assertEqual(rss, int(w.WorkingSetSize))
-
- def test_memory_vms(self):
- time.sleep(0.1)
- w = wmi.WMI().Win32_Process(ProcessId=self.pid)[0]
- p = psutil.Process(self.pid)
- vms = p.memory_info().vms
- # http://msdn.microsoft.com/en-us/library/aa394372(VS.85).aspx
- # ...claims that PageFileUsage is represented in Kilo
- # bytes but funnily enough on certain platforms bytes are
- # returned instead.
- wmi_usage = int(w.PageFileUsage)
- if (vms != wmi_usage) and (vms != wmi_usage * 1024):
- self.fail("wmi=%s, psutil=%s" % (wmi_usage, vms))
-
- def test_create_time(self):
- w = wmi.WMI().Win32_Process(ProcessId=self.pid)[0]
- p = psutil.Process(self.pid)
- wmic_create = str(w.CreationDate.split('.')[0])
- psutil_create = time.strftime("%Y%m%d%H%M%S",
- time.localtime(p.create_time()))
- self.assertEqual(wmic_create, psutil_create)
-
-
-@unittest.skipIf(not WINDOWS, "WINDOWS only")
-class TestDualProcessImplementation(unittest.TestCase):
- """
- Certain APIs on Windows have 2 internal implementations, one
- based on documented Windows APIs, another one based
- NtQuerySystemInformation() which gets called as fallback in
- case the first fails because of limited permission error.
- Here we test that the two methods return the exact same value,
- see:
- https://github.com/giampaolo/psutil/issues/304
- """
-
- @classmethod
- def setUpClass(cls):
- cls.pid = get_test_subprocess().pid
-
- @classmethod
- def tearDownClass(cls):
- reap_children()
- # ---
- # same tests as above but mimicks the AccessDenied failure of
- # the first (fast) method failing with AD.
-
- def test_name(self):
- name = psutil.Process(self.pid).name()
- with mock.patch("psutil._psplatform.cext.proc_exe",
- side_effect=psutil.AccessDenied(os.getpid())) as fun:
- self.assertEqual(psutil.Process(self.pid).name(), name)
- assert fun.called
-
- def test_memory_info(self):
- mem_1 = psutil.Process(self.pid).memory_info()
- with mock.patch("psutil._psplatform.cext.proc_memory_info",
- side_effect=OSError(errno.EPERM, "msg")) as fun:
- mem_2 = psutil.Process(self.pid).memory_info()
- self.assertEqual(len(mem_1), len(mem_2))
- for i in range(len(mem_1)):
- self.assertGreaterEqual(mem_1[i], 0)
- self.assertGreaterEqual(mem_2[i], 0)
- self.assertAlmostEqual(mem_1[i], mem_2[i], delta=512)
- assert fun.called
-
- def test_create_time(self):
- ctime = psutil.Process(self.pid).create_time()
- with mock.patch("psutil._psplatform.cext.proc_create_time",
- side_effect=OSError(errno.EPERM, "msg")) as fun:
- self.assertEqual(psutil.Process(self.pid).create_time(), ctime)
- assert fun.called
-
- def test_cpu_times(self):
- cpu_times_1 = psutil.Process(self.pid).cpu_times()
- with mock.patch("psutil._psplatform.cext.proc_cpu_times",
- side_effect=OSError(errno.EPERM, "msg")) as fun:
- cpu_times_2 = psutil.Process(self.pid).cpu_times()
- assert fun.called
- self.assertAlmostEqual(
- cpu_times_1.user, cpu_times_2.user, delta=0.01)
- self.assertAlmostEqual(
- cpu_times_1.system, cpu_times_2.system, delta=0.01)
-
- def test_io_counters(self):
- io_counters_1 = psutil.Process(self.pid).io_counters()
- with mock.patch("psutil._psplatform.cext.proc_io_counters",
- side_effect=OSError(errno.EPERM, "msg")) as fun:
- io_counters_2 = psutil.Process(self.pid).io_counters()
- for i in range(len(io_counters_1)):
- self.assertAlmostEqual(
- io_counters_1[i], io_counters_2[i], delta=5)
- assert fun.called
-
- def test_num_handles(self):
- num_handles = psutil.Process(self.pid).num_handles()
- with mock.patch("psutil._psplatform.cext.proc_num_handles",
- side_effect=OSError(errno.EPERM, "msg")) as fun:
- self.assertEqual(psutil.Process(self.pid).num_handles(),
- num_handles)
- assert fun.called
-
-
-@unittest.skipIf(not WINDOWS, "WINDOWS only")
-class RemoteProcessTestCase(unittest.TestCase):
- """Certain functions require calling ReadProcessMemory.
- This trivially works when called on the current process.
- Check that this works on other processes, especially when they
- have a different bitness.
- """
-
- @staticmethod
- def find_other_interpreter():
- # find a python interpreter that is of the opposite bitness from us
- code = "import sys; sys.stdout.write(str(sys.maxsize > 2**32))"
-
- # XXX: a different and probably more stable approach might be to access
- # the registry but accessing 64 bit paths from a 32 bit process
- for filename in glob.glob(r"C:\Python*\python.exe"):
- proc = subprocess.Popen(args=[filename, "-c", code],
- stdout=subprocess.PIPE,
- stderr=subprocess.STDOUT)
- output, _ = proc.communicate()
- if output == str(not IS_64_BIT):
- return filename
-
- @classmethod
- def setUpClass(cls):
- other_python = cls.find_other_interpreter()
-
- if other_python is None:
- raise unittest.SkipTest(
- "could not find interpreter with opposite bitness")
-
- if IS_64_BIT:
- cls.python64 = sys.executable
- cls.python32 = other_python
- else:
- cls.python64 = other_python
- cls.python32 = sys.executable
-
- test_args = ["-c", "import sys; sys.stdin.read()"]
-
- def setUp(self):
- env = os.environ.copy()
- env["THINK_OF_A_NUMBER"] = str(os.getpid())
- self.proc32 = get_test_subprocess([self.python32] + self.test_args,
- env=env,
- stdin=subprocess.PIPE)
- self.proc64 = get_test_subprocess([self.python64] + self.test_args,
- env=env,
- stdin=subprocess.PIPE)
-
- def tearDown(self):
- self.proc32.communicate()
- self.proc64.communicate()
- reap_children()
-
- @classmethod
- def tearDownClass(cls):
- reap_children()
-
- def test_cmdline_32(self):
- p = psutil.Process(self.proc32.pid)
- self.assertEqual(len(p.cmdline()), 3)
- self.assertEqual(p.cmdline()[1:], self.test_args)
-
- def test_cmdline_64(self):
- p = psutil.Process(self.proc64.pid)
- self.assertEqual(len(p.cmdline()), 3)
- self.assertEqual(p.cmdline()[1:], self.test_args)
-
- def test_cwd_32(self):
- p = psutil.Process(self.proc32.pid)
- self.assertEqual(p.cwd(), os.getcwd())
-
- def test_cwd_64(self):
- p = psutil.Process(self.proc64.pid)
- self.assertEqual(p.cwd(), os.getcwd())
-
- def test_environ_32(self):
- p = psutil.Process(self.proc32.pid)
- e = p.environ()
- self.assertIn("THINK_OF_A_NUMBER", e)
- self.assertEquals(e["THINK_OF_A_NUMBER"], str(os.getpid()))
-
- def test_environ_64(self):
- p = psutil.Process(self.proc64.pid)
- e = p.environ()
- self.assertIn("THINK_OF_A_NUMBER", e)
- self.assertEquals(e["THINK_OF_A_NUMBER"], str(os.getpid()))
-
-
-# ===================================================================
-# Windows services
-# ===================================================================
-
-
-@unittest.skipIf(not WINDOWS, "WINDOWS only")
-class TestServices(unittest.TestCase):
-
- def test_win_service_iter(self):
- valid_statuses = set([
- "running",
- "paused",
- "start",
- "pause",
- "continue",
- "stop",
- "stopped",
- ])
- valid_start_types = set([
- "automatic",
- "manual",
- "disabled",
- ])
- valid_statuses = set([
- "running",
- "paused",
- "start_pending",
- "pause_pending",
- "continue_pending",
- "stop_pending",
- "stopped"
- ])
- for serv in psutil.win_service_iter():
- data = serv.as_dict()
- self.assertIsInstance(data['name'], str)
- self.assertNotEqual(data['name'].strip(), "")
- self.assertIsInstance(data['display_name'], str)
- self.assertIsInstance(data['username'], str)
- self.assertIn(data['status'], valid_statuses)
- if data['pid'] is not None:
- psutil.Process(data['pid'])
- self.assertIsInstance(data['binpath'], str)
- self.assertIsInstance(data['username'], str)
- self.assertIsInstance(data['start_type'], str)
- self.assertIn(data['start_type'], valid_start_types)
- self.assertIn(data['status'], valid_statuses)
- self.assertIsInstance(data['description'], str)
- pid = serv.pid()
- if pid is not None:
- p = psutil.Process(pid)
- self.assertTrue(p.is_running())
- # win_service_get
- s = psutil.win_service_get(serv.name())
- # test __eq__
- self.assertEqual(serv, s)
-
- def test_win_service_get(self):
- name = next(psutil.win_service_iter()).name()
-
- with self.assertRaises(psutil.NoSuchProcess) as cm:
- psutil.win_service_get(name + '???')
- self.assertEqual(cm.exception.name, name + '???')
-
- # test NoSuchProcess
- service = psutil.win_service_get(name)
- exc = WindowsError(
- psutil._psplatform.cext.ERROR_SERVICE_DOES_NOT_EXIST, "")
- with mock.patch("psutil._psplatform.cext.winservice_query_status",
- side_effect=exc):
- self.assertRaises(psutil.NoSuchProcess, service.status)
- with mock.patch("psutil._psplatform.cext.winservice_query_config",
- side_effect=exc):
- self.assertRaises(psutil.NoSuchProcess, service.username)
-
- # test AccessDenied
- exc = WindowsError(
- psutil._psplatform.cext.ERROR_ACCESS_DENIED, "")
- with mock.patch("psutil._psplatform.cext.winservice_query_status",
- side_effect=exc):
- self.assertRaises(psutil.AccessDenied, service.status)
- with mock.patch("psutil._psplatform.cext.winservice_query_config",
- side_effect=exc):
- self.assertRaises(psutil.AccessDenied, service.username)
-
- # test __str__ and __repr__
- self.assertIn(service.name(), str(service))
- self.assertIn(service.display_name(), str(service))
- self.assertIn(service.name(), repr(service))
- self.assertIn(service.display_name(), repr(service))
-
-
-if __name__ == '__main__':
- run_test_module_by_name(__file__)