summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGiampaolo Rodola <g.rodola@gmail.com>2020-02-11 09:30:25 -0800
committerGiampaolo Rodola <g.rodola@gmail.com>2020-02-11 09:30:25 -0800
commita95ae23a5fd40d1b0182f38c1db71b930ff0b6e0 (patch)
tree3baed4d085b2333229e875a856cafa5a72d3610e
parenta1c7bee3f45b30fae61a724f4bcc142e74cc8fc5 (diff)
parentd8cb832f8cc7ef2695472ec0f752c59c72916274 (diff)
downloadpsutil-a95ae23a5fd40d1b0182f38c1db71b930ff0b6e0.tar.gz
Merge branch 'master' of https://github.com/giampaolo/psutil
-rw-r--r--.github/ISSUE_TEMPLATE/bug.md21
-rw-r--r--.travis.yml2
-rw-r--r--HISTORY.rst11
-rw-r--r--README.rst2
-rw-r--r--docs/DEVGUIDE.rst4
-rw-r--r--docs/index.rst10
-rw-r--r--psutil/_common.py12
-rw-r--r--psutil/_pslinux.py34
-rw-r--r--psutil/_pssunos.py8
-rw-r--r--psutil/_psutil_common.h23
-rw-r--r--psutil/_psutil_linux.c2
-rw-r--r--psutil/arch/windows/socks.c108
-rw-r--r--psutil/tests/__init__.py1
-rwxr-xr-xpsutil/tests/test_linux.py39
-rwxr-xr-xpsutil/tests/test_memory_leaks.py11
-rwxr-xr-xpsutil/tests/test_process.py3
-rw-r--r--psutil/tests/test_unicode.py1
17 files changed, 178 insertions, 114 deletions
diff --git a/.github/ISSUE_TEMPLATE/bug.md b/.github/ISSUE_TEMPLATE/bug.md
index ba4a026c..67a9601b 100644
--- a/.github/ISSUE_TEMPLATE/bug.md
+++ b/.github/ISSUE_TEMPLATE/bug.md
@@ -6,23 +6,14 @@ labels: 'bug'
---
**Platform**
-* { OS version } (also add appropriate OS issue label (linux, windows, ...))
-* { psutil version } (use "pip show psutil")
+* { OS version }
+* { psutil version: python3 -c "import psutil; print(psutil.__version__)" }
+* { python version }
-**Bug description**
-{ a clear and concise description of what the bug is }
-```
-traceback message (if any)
-```
+**Bug description**
+...
-```python
-code to reproduce the problem (if any)
-```
**Test results**
-```
-output of `python -c psutil.tests` (failures only, not full result)
-```
-{ you may want to do this in order to discover other issues affecting your platform }
-{ if failures look unrelated with the issue at hand open another ticket }
+{ output of `python -c psutil.tests` (failures only, not full result) }
diff --git a/.travis.yml b/.travis.yml
index ced00a09..fad35121 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -18,7 +18,7 @@ matrix:
- python: 3.8
# pypy
# - python: pypy
- # - python: pypy3
+ - python: pypy3
install:
- ./.ci/travis/install.sh
script:
diff --git a/HISTORY.rst b/HISTORY.rst
index 7bb4fffa..68309241 100644
--- a/HISTORY.rst
+++ b/HISTORY.rst
@@ -16,10 +16,14 @@ XXXX-XX-XX
- 1671_: [FreeBSD] add CI testing/service for FreeBSD (Cirrus CI).
- 1677_: [Windows] process exe() will succeed for all process PIDs (instead of
raising AccessDenied).
+- 1679_: [Windows] net_connections() and Process.connections() are 10% faster.
+- 1681_: [Linux] disk_partitions() now also shows swap partitions.
+
**Bug fixes**
- 1538_: [NetBSD] process cwd() may return ENOENT instead of NoSuchProcess.
+- 1627_: [Linux] Process.memory_maps() can raise KeyError.
- 1642_: [SunOS] querying basic info for PID 0 results in FileNotFoundError.
- 1646_: [FreeBSD] many Process methods may cause a segfault on FreeBSD 12.0
due to a backward incompatible change in a C type introduced in 12.0.
@@ -32,6 +36,9 @@ XXXX-XX-XX
- 1672_: properly handle PID C type.
- 1673_: [OpenBSD] Process connections(), num_fds() and threads() returned
improper exception if process is gone.
+- 1674_: [SunOS] disk_partitions() may raise OSError.
+- 1684_: [Linux] disk_io_counters() may raise ValueError on systems not
+ having /proc/diskstats.
5.6.7
=====
@@ -52,7 +59,9 @@ XXXX-XX-XX
- 1179_: [Linux] Process cmdline() now takes into account misbehaving processes
renaming the command line and using inappropriate chars to separate args.
- 1616_: use of Py_DECREF instead of Py_CLEAR will result in double free and
- segfault (CVE). (patch by Riccardo Schirone)
+ segfault
+ (`CVE-2019-18874 <https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-18874>`__).
+ (patch by Riccardo Schirone)
- 1619_: [OpenBSD] compilation fails due to C syntax error. (patch by Nathan
Houghton)
diff --git a/README.rst b/README.rst
index 57c30d6c..8fadf4a3 100644
--- a/README.rst
+++ b/README.rst
@@ -22,7 +22,7 @@
:target: https://www.codacy.com/app/g-rodola/psutil?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=giampaolo/psutil&amp;utm_campaign=Badge_Grade
:alt: Code quality
-.. |travis| image:: https://img.shields.io/travis/giampaolo/psutil/master.svg?maxAge=3600&label=Linux%20/%20OSX
+.. |travis| image:: https://img.shields.io/travis/giampaolo/psutil/master.svg?maxAge=3600&label=Linux,%20OSX,%20PyPy
:target: https://travis-ci.org/giampaolo/psutil
:alt: Linux tests (Travis)
diff --git a/docs/DEVGUIDE.rst b/docs/DEVGUIDE.rst
index 5ef1c4e4..598c8b61 100644
--- a/docs/DEVGUIDE.rst
+++ b/docs/DEVGUIDE.rst
@@ -141,9 +141,9 @@ Both services run psutil test suite against all supported python version
(2.6 - 3.6).
Two icons in the home page (README) always show the build status:
-.. image:: https://img.shields.io/travis/giampaolo/psutil/master.svg?maxAge=3600&label=Linux%20/%20macOS
+.. image:: https://img.shields.io/travis/giampaolo/psutil/master.svg?maxAge=3600&label=Linux,%20OSX,%20PyPy
:target: https://travis-ci.org/giampaolo/psutil
- :alt: Linux and macOS tests (Travis)
+ :alt: Linux, macOS and PyPy3 tests (Travis)
.. image:: https://img.shields.io/appveyor/ci/giampaolo/psutil/master.svg?maxAge=3600&label=Windows
:target: https://ci.appveyor.com/project/giampaolo/psutil
diff --git a/docs/index.rst b/docs/index.rst
index 74dddd23..97dce444 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -186,8 +186,10 @@ CPU
Return the number of logical CPUs in the system (same as `os.cpu_count`_
in Python 3.4) or ``None`` if undetermined.
- If *logical* is ``False`` return the number of physical cores only (hyper
- thread CPUs are excluded) or ``None`` if undetermined.
+ *logical* cores means the number of physical cores multiplied by the number
+ of threads that can run on each core (this is known as Hyper Threading).
+ If *logical* is ``False`` return the number of physical cores only (Hyper
+ Thread CPUs are excluded) or ``None`` if undetermined.
On OpenBSD and NetBSD ``psutil.cpu_count(logical=False)`` always return
``None``.
Example on a system having 2 physical hyper-thread CPU cores:
@@ -386,7 +388,7 @@ Disks
mount point and filesystem type, similarly to "df" command on UNIX. If *all*
parameter is ``False`` it tries to distinguish and return physical devices
only (e.g. hard disks, cd-rom drives, USB keys) and ignore all others
- (e.g. memory partitions such as /dev/shm).
+ (e.g. pseudo, memory, duplicate, inaccessible filesystems).
Note that this may not be fully reliable on all systems (e.g. on BSD this
parameter is ignored).
Named tuple's **fstype** field is a string which varies depending on the
@@ -403,6 +405,8 @@ Disks
[sdiskpart(device='/dev/sda3', mountpoint='/', fstype='ext4', opts='rw,errors=remount-ro'),
sdiskpart(device='/dev/sda7', mountpoint='/home', fstype='ext4', opts='rw')]
+ .. versionchanged:: 5.7.0 swap partitions are shown on Linux.
+
.. function:: disk_usage(path)
Return disk usage statistics about the partition which contains the given
diff --git a/psutil/_common.py b/psutil/_common.py
index 729b1983..453c771d 100644
--- a/psutil/_common.py
+++ b/psutil/_common.py
@@ -7,7 +7,7 @@
# Note: this module is imported by setup.py so it should not import
# psutil or third-party modules.
-from __future__ import division
+from __future__ import division, print_function
import contextlib
import errno
@@ -66,7 +66,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', 'conn_to_ntuple', 'hilite',
+ 'bytes2human', 'conn_to_ntuple', 'hilite', 'debug',
]
@@ -787,3 +787,11 @@ def hilite(s, ok=True, bold=False):
if bold:
attr.append('1')
return '\x1b[%sm%s\x1b[0m' % (';'.join(attr), s)
+
+
+if bool(os.getenv('PSUTIL_DEBUG', 0)):
+ def debug(msg):
+ print("psutil-debug> " + msg, file=sys.stderr)
+else:
+ def debug(msg):
+ pass
diff --git a/psutil/_pslinux.py b/psutil/_pslinux.py
index 06935111..eb03e8a3 100644
--- a/psutil/_pslinux.py
+++ b/psutil/_pslinux.py
@@ -26,6 +26,7 @@ from . import _psposix
from . import _psutil_linux as cext
from . import _psutil_posix as cext_posix
from ._common import AccessDenied
+from ._common import debug
from ._common import decode
from ._common import get_procfs_path
from ._common import isfile_strict
@@ -1105,7 +1106,7 @@ def disk_io_counters(perdisk=False):
fields = f.read().strip().split()
name = os.path.basename(root)
(reads, reads_merged, rbytes, rtime, writes, writes_merged,
- wbytes, wtime, _, busy_time, _) = map(int, fields)
+ wbytes, wtime, _, busy_time) = map(int, fields[:10])
yield (name, reads, writes, rbytes, wbytes, rtime,
wtime, reads_merged, writes_merged, busy_time)
@@ -1176,6 +1177,32 @@ def disk_partitions(all=False):
continue
ntuple = _common.sdiskpart(device, mountpoint, fstype, opts)
retlist.append(ntuple)
+
+ # swap
+ if all:
+ try:
+ f = open_text("%s/swaps" % procfs_path)
+ except FileNotFoundError:
+ pass
+ else:
+ with f:
+ f.readline() # header
+ for line in f.readlines():
+ fields = line.split('\t')
+ device = fields[0].split()[0]
+ mountp = None
+ fstype = 'swap'
+ # The priority column is useful when multiple swap
+ # files are in use. The lower the priority, the
+ # more likely the swap file is to be used.
+ prio = fields[-1].strip()
+ if re.match(r'(-)?\d+', prio):
+ opts = "priority=" + prio
+ else:
+ opts = ''
+ ntuple = _common.sdiskpart(device, mountp, fstype, opts)
+ retlist.append(ntuple)
+
return retlist
@@ -1253,8 +1280,7 @@ def sensors_temperatures():
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)
+ debug("ignoring %r for file %r" % (err, path))
continue
trip_paths = glob.glob(base + '/trip_point*')
@@ -1842,7 +1868,7 @@ class Process(object):
path = path[:-10]
ls.append((
decode(addr), decode(perms), path,
- data[b'Rss:'],
+ data.get(b'Rss:', 0),
data.get(b'Size:', 0),
data.get(b'Pss:', 0),
data.get(b'Shared_Clean:', 0),
diff --git a/psutil/_pssunos.py b/psutil/_pssunos.py
index b1e2d1c9..62362b89 100644
--- a/psutil/_pssunos.py
+++ b/psutil/_pssunos.py
@@ -19,6 +19,7 @@ from . import _psutil_posix as cext_posix
from . import _psutil_sunos as cext
from ._common import AccessDenied
from ._common import AF_INET6
+from ._common import debug
from ._common import get_procfs_path
from ._common import isfile_strict
from ._common import memoize_when_activated
@@ -225,7 +226,12 @@ def disk_partitions(all=False):
# Differently from, say, Linux, we don't have a list of
# common fs types so the best we can do, AFAIK, is to
# filter by filesystem having a total size > 0.
- if not disk_usage(mountpoint).total:
+ try:
+ if not disk_usage(mountpoint).total:
+ continue
+ except OSError as err:
+ # https://github.com/giampaolo/psutil/issues/1674
+ debug("skipping %r: %r" % (mountpoint, err))
continue
ntuple = _common.sdiskpart(device, mountpoint, fstype, opts)
retlist.append(ntuple)
diff --git a/psutil/_psutil_common.h b/psutil/_psutil_common.h
index 60ea6298..2fccab81 100644
--- a/psutil/_psutil_common.h
+++ b/psutil/_psutil_common.h
@@ -27,15 +27,22 @@ static const int PSUTIL_CONN_NONE = 128;
#define PyUnicode_DecodeFSDefaultAndSize PyString_FromStringAndSize
#endif
-// Python 2: SIZEOF_PID_T not defined but _getpid() returns an int.
-#if defined(PSUTIL_WINDOWS) && !defined(SIZEOF_PID_T)
- #define SIZEOF_PID_T SIZEOF_INT
+// --- _Py_PARSE_PID
+
+// SIZEOF_INT|LONG is missing on Linux + PyPy (only?).
+// SIZEOF_PID_T is missing on Windows + Python2.
+// In we can't determine pid_t size we assume it's an (int).
+// On major UNIX platforms I've seen pid_t is treated as int.
+// _getpid() on Windows returns an int. We can't be 100% sure though,
+// (in that case we'd probably get compiler warnings).
+#if !defined(SIZEOF_INT)
+ #define SIZEOF_INT 4
#endif
-
-#if !defined(_Py_PARSE_PID) || PY_MAJOR_VERSION < 3
- #if !defined(SIZEOF_PID_T) || !defined(SIZEOF_INT) || !defined(SIZEOF_LONG)
- #error "missing SIZEOF* definition"
- #endif
+#if !defined(SIZEOF_LONG)
+ #define SIZEOF_LONG 8
+#endif
+#if !defined(SIZEOF_PID_T)
+ #define SIZEOF_PID_T 4 // assume int
#endif
// _Py_PARSE_PID is Python 3 only, but since it's private make sure it's
diff --git a/psutil/_psutil_linux.c b/psutil/_psutil_linux.c
index 93cc071b..ec8b433a 100644
--- a/psutil/_psutil_linux.c
+++ b/psutil/_psutil_linux.c
@@ -204,7 +204,7 @@ static PyObject *
psutil_disk_partitions(PyObject *self, PyObject *args) {
FILE *file = NULL;
struct mntent *entry;
- const char *mtab_path;
+ char *mtab_path;
PyObject *py_dev = NULL;
PyObject *py_mountp = NULL;
PyObject *py_tuple = NULL;
diff --git a/psutil/arch/windows/socks.c b/psutil/arch/windows/socks.c
index 61f18c07..5e4c2df8 100644
--- a/psutil/arch/windows/socks.c
+++ b/psutil/arch/windows/socks.c
@@ -18,79 +18,89 @@
#define BYTESWAP_USHORT(x) ((((USHORT)(x) << 8) | ((USHORT)(x) >> 8)) & 0xffff)
#define STATUS_UNSUCCESSFUL 0xC0000001
+ULONG g_TcpTableSize = 0;
+ULONG g_UdpTableSize = 0;
+
// Note about GetExtended[Tcp|Udp]Table syscalls: due to other processes
// being active on the machine, it's possible that the size of the table
-// increases between the moment where we query the size and the moment
-// where we query the data. Therefore we call them in a loop to retry if
-// that happens. See:
+// increases between the moment we query the size and the moment we query
+// the data. Therefore we retry if that happens. See:
// https://github.com/giampaolo/psutil/pull/1335
// https://github.com/giampaolo/psutil/issues/1294
+// A global and ever increasing size is used in order to avoid calling
+// GetExtended[Tcp|Udp]Table twice per call (faster).
static PVOID __GetExtendedTcpTable(ULONG family) {
DWORD err;
PVOID table;
- ULONG size = 0;
-
- while (1) {
- // get table size
- GetExtendedTcpTable(NULL, &size, FALSE, family,
- TCP_TABLE_OWNER_PID_ALL, 0);
+ ULONG size;
+ TCP_TABLE_CLASS class = TCP_TABLE_OWNER_PID_ALL;
+
+ size = g_TcpTableSize;
+ if (size == 0) {
+ GetExtendedTcpTable(NULL, &size, FALSE, family, class, 0);
+ // reserve 25% more space
+ size = size + (size / 2 / 2);
+ g_TcpTableSize = size;
+ }
- table = malloc(size);
- if (table == NULL) {
- PyErr_NoMemory();
- return NULL;
- }
+ table = malloc(size);
+ if (table == NULL) {
+ PyErr_NoMemory();
+ return NULL;
+ }
- // get connections
- err = GetExtendedTcpTable(table, &size, FALSE, family,
- TCP_TABLE_OWNER_PID_ALL, 0);
- if (err == NO_ERROR)
- return table;
+ err = GetExtendedTcpTable(table, &size, FALSE, family, class, 0);
+ if (err == NO_ERROR)
+ return table;
- free(table);
- if (err == ERROR_INSUFFICIENT_BUFFER || err == STATUS_UNSUCCESSFUL) {
- psutil_debug("GetExtendedTcpTable: retry with different bufsize");
- continue;
- }
- PyErr_SetString(PyExc_RuntimeError, "GetExtendedTcpTable failed");
- return NULL;
+ free(table);
+ if (err == ERROR_INSUFFICIENT_BUFFER || err == STATUS_UNSUCCESSFUL) {
+ psutil_debug("GetExtendedTcpTable: retry with different bufsize");
+ g_TcpTableSize = 0;
+ return __GetExtendedTcpTable(family);
}
+
+ PyErr_SetString(PyExc_RuntimeError, "GetExtendedTcpTable failed");
+ return NULL;
}
static PVOID __GetExtendedUdpTable(ULONG family) {
DWORD err;
PVOID table;
- ULONG size = 0;
-
- while (1) {
- // get table size
- GetExtendedUdpTable(NULL, &size, FALSE, family,
- UDP_TABLE_OWNER_PID, 0);
+ ULONG size;
+ UDP_TABLE_CLASS class = UDP_TABLE_OWNER_PID;
+
+ size = g_UdpTableSize;
+ if (size == 0) {
+ GetExtendedUdpTable(NULL, &size, FALSE, family, class, 0);
+ // reserve 25% more space
+ size = size + (size / 2 / 2);
+ g_UdpTableSize = size;
+ }
- table = malloc(size);
- if (table == NULL) {
- PyErr_NoMemory();
- return NULL;
- }
+ table = malloc(size);
+ if (table == NULL) {
+ PyErr_NoMemory();
+ return NULL;
+ }
- // get connections
- err = GetExtendedUdpTable(table, &size, FALSE, family,
- UDP_TABLE_OWNER_PID, 0);
- if (err == NO_ERROR)
- return table;
+ err = GetExtendedUdpTable(table, &size, FALSE, family, class, 0);
+ if (err == NO_ERROR)
+ return table;
- free(table);
- if (err == ERROR_INSUFFICIENT_BUFFER || err == STATUS_UNSUCCESSFUL) {
- psutil_debug("GetExtendedUdpTable: retry with different bufsize");
- continue;
- }
- PyErr_SetString(PyExc_RuntimeError, "GetExtendedUdpTable failed");
- return NULL;
+ free(table);
+ if (err == ERROR_INSUFFICIENT_BUFFER || err == STATUS_UNSUCCESSFUL) {
+ psutil_debug("GetExtendedUdpTable: retry with different bufsize");
+ g_UdpTableSize = 0;
+ return __GetExtendedUdpTable(family);
}
+
+ PyErr_SetString(PyExc_RuntimeError, "GetExtendedUdpTable failed");
+ return NULL;
}
diff --git a/psutil/tests/__init__.py b/psutil/tests/__init__.py
index 5251983f..8a373386 100644
--- a/psutil/tests/__init__.py
+++ b/psutil/tests/__init__.py
@@ -113,7 +113,6 @@ __all__ = [
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 a Continuous Integration service
TRAVIS = bool(os.environ.get('TRAVIS'))
APPVEYOR = bool(os.environ.get('APPVEYOR'))
diff --git a/psutil/tests/test_linux.py b/psutil/tests/test_linux.py
index 80bbd113..4736bd6b 100755
--- a/psutil/tests/test_linux.py
+++ b/psutil/tests/test_linux.py
@@ -316,7 +316,7 @@ class TestSystemVirtualMemory(unittest.TestCase):
@retry_on_failure()
def test_avail_old_percent(self):
# Make sure that our calculation of avail mem for old kernels
- # is off by max 10%.
+ # is off by max 15%.
from psutil._pslinux import calculate_avail_vmem
from psutil._pslinux import open_binary
@@ -330,7 +330,7 @@ class TestSystemVirtualMemory(unittest.TestCase):
if b'MemAvailable:' in mems:
b = mems[b'MemAvailable:']
diff_percent = abs(a - b) / a * 100
- self.assertLess(diff_percent, 10)
+ self.assertLess(diff_percent, 15)
def test_avail_old_comes_from_kernel(self):
# Make sure "MemAvailable:" coluimn is used instead of relying
@@ -1067,6 +1067,22 @@ class TestSystemDiskPartitions(unittest.TestCase):
finally:
psutil.PROCFS_PATH = "/proc"
+ @unittest.skipIf(not os.path.exists('/proc/swaps'),
+ "/proc/swaps not available")
+ def test_swap(self):
+ types = [x.fstype for x in psutil.disk_partitions(all=False)]
+ self.assertNotIn('swap', types)
+ types = [x.fstype for x in psutil.disk_partitions(all=True)]
+ self.assertIn('swap', types)
+ for part in psutil.disk_partitions(all=True):
+ if part.fstype == 'swap':
+ assert os.path.exists(part.device), part
+ self.assertIsNone(part.mountpoint)
+ if part.opts:
+ assert part.opts.startswith('priority=')
+ prio = part.opts.split('=')[1]
+ int(prio)
+
@unittest.skipIf(not LINUX, "LINUX only")
class TestSystemDiskIoCounters(unittest.TestCase):
@@ -1548,25 +1564,6 @@ class TestSensorsBattery(unittest.TestCase):
@unittest.skipIf(not LINUX, "LINUX only")
class TestSensorsTemperatures(unittest.TestCase):
- @unittest.skipIf(TRAVIS, "unreliable on TRAVIS")
- @unittest.skipIf(LINUX and EMPTY_TEMPERATURES, "no temperatures")
- def test_emulate_eio_error(self):
- def open_mock(name, *args, **kwargs):
- if name.endswith("_input"):
- raise OSError(errno.EIO, "")
- elif name.endswith("temp"):
- 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_class_hwmon(self):
def open_mock(name, *args, **kwargs):
if name.endswith('/name'):
diff --git a/psutil/tests/test_memory_leaks.py b/psutil/tests/test_memory_leaks.py
index 132a0b07..31a632a4 100755
--- a/psutil/tests/test_memory_leaks.py
+++ b/psutil/tests/test_memory_leaks.py
@@ -11,6 +11,8 @@ 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).
+PyPy appears to be completely unstable for this framework, probably
+because of how its JIT handles memory, so tests are skipped.
"""
from __future__ import print_function
@@ -39,7 +41,6 @@ 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_GETLOADAVG
from psutil.tests import HAS_IONICE
from psutil.tests import HAS_MEMORY_MAPS
from psutil.tests import HAS_NET_IO_COUNTERS
@@ -49,6 +50,7 @@ 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 PYPY
from psutil.tests import reap_children
from psutil.tests import safe_rmpath
from psutil.tests import skip_on_access_denied
@@ -57,14 +59,14 @@ from psutil.tests import TRAVIS
from psutil.tests import unittest
+# configurable opts
LOOPS = 1000
MEMORY_TOLERANCE = 4096
RETRY_FOR = 3
+SKIP_PYTHON_IMPL = True
-SKIP_PYTHON_IMPL = True if TRAVIS else False
cext = psutil._psplatform.cext
thisproc = psutil.Process()
-SKIP_PYTHON_IMPL = True if TRAVIS else False
# ===================================================================
@@ -77,6 +79,7 @@ def skip_if_linux():
"worthless on LINUX (pure python)")
+@unittest.skipIf(PYPY, "unreliable on PYPY")
class TestMemLeak(unittest.TestCase):
"""Base framework class which calls a function many times and
produces a failure if process memory usage keeps increasing
@@ -477,7 +480,7 @@ class TestModuleFunctionsLeaks(TestMemLeak):
def test_cpu_freq(self):
self.execute(psutil.cpu_freq)
- @unittest.skipIf(not HAS_GETLOADAVG, "not supported")
+ @unittest.skipIf(not WINDOWS, "WINDOWS only")
def test_getloadavg(self):
self.execute(psutil.getloadavg)
diff --git a/psutil/tests/test_process.py b/psutil/tests/test_process.py
index 5728f183..0277a56a 100755
--- a/psutil/tests/test_process.py
+++ b/psutil/tests/test_process.py
@@ -727,6 +727,7 @@ class TestProcess(unittest.TestCase):
else:
raise
+ @unittest.skipIf(PYPY, "broken on PYPY")
def test_long_cmdline(self):
create_exe(TESTFN)
self.addCleanup(safe_rmpath, TESTFN)
@@ -741,6 +742,7 @@ class TestProcess(unittest.TestCase):
pyexe = os.path.basename(os.path.realpath(sys.executable)).lower()
assert pyexe.startswith(name), (pyexe, name)
+ @unittest.skipIf(PYPY, "unreliable on PYPY")
def test_long_name(self):
long_name = TESTFN + ("0123456789" * 2)
create_exe(long_name)
@@ -752,6 +754,7 @@ class TestProcess(unittest.TestCase):
# XXX
@unittest.skipIf(SUNOS, "broken on SUNOS")
@unittest.skipIf(AIX, "broken on AIX")
+ @unittest.skipIf(PYPY, "broken on PYPY")
def test_prog_w_funky_name(self):
# Test that name(), exe() and cmdline() correctly handle programs
# with funky chars such as spaces and ")", see:
diff --git a/psutil/tests/test_unicode.py b/psutil/tests/test_unicode.py
index 91395ebf..eecd7dc4 100644
--- a/psutil/tests/test_unicode.py
+++ b/psutil/tests/test_unicode.py
@@ -298,6 +298,7 @@ class TestFSAPIs(_BaseFSAPIsTests, unittest.TestCase):
@unittest.skipIf(PYPY and TRAVIS, "unreliable on PYPY + TRAVIS")
@unittest.skipIf(MACOS and TRAVIS, "unreliable on TRAVIS") # TODO
+@unittest.skipIf(PYPY, "unreliable on PYPY")
@unittest.skipIf(not subprocess_supports_unicode(INVALID_NAME),
"subprocess can't deal with invalid unicode")
class TestFSAPIsWithInvalidPath(_BaseFSAPIsTests, unittest.TestCase):