Skip to content
This repository has been archived by the owner on Jun 22, 2024. It is now read-only.

Commit

Permalink
Merge branch 'giampaolo-master'
Browse files Browse the repository at this point in the history
* giampaolo-master:
  revert prev commit which broke one test
  netbsd / cwd: raise NSP on ENOENT (giampaolo#2340)
  fix failing tests
  fix win test
  fix windows unicode tests
  fix some win tests + upgrade BSD* vmactions
  • Loading branch information
ddelange committed Dec 20, 2023
2 parents 30ed5ee + 2dfc5de commit c677cb1
Show file tree
Hide file tree
Showing 11 changed files with 111 additions and 51 deletions.
14 changes: 7 additions & 7 deletions .github/workflows/bsd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@ concurrency:
cancel-in-progress: true
jobs:
freebsd:
runs-on: macos-12
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4
- name: Run tests
uses: vmactions/freebsd-vm@v0
uses: vmactions/freebsd-vm@v1
with:
usesh: true
prepare: |
Expand All @@ -28,11 +28,11 @@ jobs:
make test
make test-memleaks
openbsd:
runs-on: macos-12
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4
- name: Run tests
uses: vmactions/openbsd-vm@v0
uses: vmactions/openbsd-vm@v1
with:
usesh: true
prepare: |
Expand All @@ -46,16 +46,16 @@ jobs:
make test
make test-memleaks
netbsd:
runs-on: macos-12
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4
- name: Run tests
uses: vmactions/netbsd-vm@v0
uses: vmactions/netbsd-vm@v1
with:
usesh: true
prepare: |
set -e
pkg_add -v pkgin
/usr/sbin/pkg_add -v pkgin
pkgin update
pkgin -y install python311-* py311-setuptools-* gcc12-*
run: |
Expand Down
6 changes: 6 additions & 0 deletions HISTORY.rst
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
*Bug tracker at https://github.com/giampaolo/psutil/issues*

5.9.8 (IN DEVELOPMENT)
======================

- 2340_, [NetBSD]: if process is terminated, `Process.cwd()`_ will return an
empty string instead of raising `NoSuchProcess`_.

5.9.7
=====

Expand Down
2 changes: 1 addition & 1 deletion psutil/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@
AF_LINK = _psplatform.AF_LINK

__author__ = "Giampaolo Rodola'"
__version__ = "5.9.7"
__version__ = "5.9.8"
version_info = tuple([int(num) for num in __version__.split('.')])

_timer = getattr(time, 'monotonic', time.time)
Expand Down
9 changes: 3 additions & 6 deletions psutil/arch/netbsd/proc.c
Original file line number Diff line number Diff line change
Expand Up @@ -115,13 +115,10 @@ psutil_proc_cwd(PyObject *self, PyObject *args) {
ssize_t len = readlink(buf, path, sizeof(path) - 1);
free(buf);
if (len == -1) {
if (errno == ENOENT) {
psutil_debug("sysctl(KERN_PROC_CWD) -> ENOENT converted to ''");
return Py_BuildValue("s", "");
}
else {
if (errno == ENOENT)
NoSuchProcess("sysctl -> ENOENT");
else
PyErr_SetFromErrno(PyExc_OSError);
}
return NULL;
}
path[len] = '\0';
Expand Down
26 changes: 26 additions & 0 deletions psutil/tests/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@
'unittest', 'skip_on_access_denied', 'skip_on_not_implemented',
'retry_on_failure', 'TestMemoryLeak', 'PsutilTestCase',
'process_namespace', 'system_namespace', 'print_sysinfo',
'is_win_secure_system_proc',
# fs utils
'chdir', 'safe_rmpath', 'create_exe', 'get_testfn',
# os
Expand Down Expand Up @@ -1301,6 +1302,31 @@ def print_sysinfo():
print("=" * 70, file=sys.stderr) # NOQA
sys.stdout.flush()

if WINDOWS:
os.system("tasklist")
elif which("ps"):
os.system("ps aux")
print("=" * 70, file=sys.stderr) # NOQA
sys.stdout.flush()


def is_win_secure_system_proc(pid):
# see: https://github.com/giampaolo/psutil/issues/2338
@memoize
def get_procs():
ret = {}
out = sh("tasklist.exe /NH /FO csv")
for line in out.splitlines()[1:]:
bits = [x.replace('"', "") for x in line.split(",")]
name, pid = bits[0], int(bits[1])
ret[pid] = name
return ret

try:
return get_procs()[pid] == "Secure System"
except KeyError:
return False


def _get_eligible_cpu():
p = psutil.Process()
Expand Down
14 changes: 8 additions & 6 deletions psutil/tests/test_contracts.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@
from psutil._compat import long
from psutil._compat import range
from psutil._compat import unicode
from psutil.tests import APPVEYOR
from psutil.tests import CI_TESTING
from psutil.tests import GITHUB_ACTIONS
from psutil.tests import HAS_CPU_FREQ
Expand All @@ -52,6 +51,7 @@
from psutil.tests import create_sockets
from psutil.tests import enum
from psutil.tests import is_namedtuple
from psutil.tests import is_win_secure_system_proc
from psutil.tests import kernel_version
from psutil.tests import process_namespace
from psutil.tests import serialrun
Expand Down Expand Up @@ -447,8 +447,8 @@ def test_all(self):
meth(value, info)
except Exception:
s = '\n' + '=' * 70 + '\n'
s += "FAIL: name=test_%s, pid=%s, ret=%s\n" % (
name, info['pid'], repr(value))
s += "FAIL: name=test_%s, pid=%s, ret=%s\ninfo=%s\n" % (
name, info['pid'], repr(value), info)
s += '-' * 70
s += "\n%s" % traceback.format_exc()
s = "\n".join((" " * 4) + i for i in s.splitlines()) + "\n"
Expand Down Expand Up @@ -494,11 +494,12 @@ def ppid(self, ret, info):

def name(self, ret, info):
self.assertIsInstance(ret, (str, unicode))
if APPVEYOR and not ret and info['status'] == 'stopped':
if WINDOWS and not ret and is_win_secure_system_proc(info['pid']):
# https://github.com/giampaolo/psutil/issues/2338
return
# on AIX, "<exiting>" processes don't have names
if not AIX:
assert ret
assert ret, repr(ret)

def create_time(self, ret, info):
self.assertIsInstance(ret, float)
Expand Down Expand Up @@ -567,7 +568,8 @@ def ionice(self, ret, info):

def num_threads(self, ret, info):
self.assertIsInstance(ret, int)
if APPVEYOR and not ret and info['status'] == 'stopped':
if WINDOWS and ret == 0 and is_win_secure_system_proc(info['pid']):
# https://github.com/giampaolo/psutil/issues/2338
return
self.assertGreaterEqual(ret, 1)

Expand Down
3 changes: 3 additions & 0 deletions psutil/tests/test_memleaks.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import psutil._common
from psutil import LINUX
from psutil import MACOS
from psutil import NETBSD
from psutil import OPENBSD
from psutil import POSIX
from psutil import SUNOS
Expand Down Expand Up @@ -249,6 +250,7 @@ def test_rlimit_set(self):
# Windows implementation is based on a single system-wide
# function (tested later).
@unittest.skipIf(WINDOWS, "worthless on WINDOWS")
@unittest.skipIf(NETBSD, "critically broken on NETBSD (#930)")
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
Expand Down Expand Up @@ -422,6 +424,7 @@ def test_net_io_counters(self):

@fewtimes_if_linux()
@unittest.skipIf(MACOS and os.getuid() != 0, "need root access")
@unittest.skipIf(NETBSD, "critically broken on NETBSD (#930)")
def test_net_connections(self):
# always opens and handle on Windows() (once)
psutil.net_connections(kind='all')
Expand Down
16 changes: 10 additions & 6 deletions psutil/tests/test_process.py
Original file line number Diff line number Diff line change
Expand Up @@ -765,7 +765,8 @@ def test_name(self):
def test_long_name(self):
testfn = self.get_testfn(suffix="0123456789" * 2)
create_exe(testfn)
p = self.spawn_psproc(testfn)
cmdline = [testfn] + (["0123456789"] * 20)
p = self.spawn_psproc(cmdline)
if OPENBSD:
# XXX: for some reason the test process may turn into a
# zombie (don't know why). Because the name() is long, all
Expand Down Expand Up @@ -838,9 +839,6 @@ def test_nice(self):
init = p.nice()
try:
if WINDOWS:
# A CI runner may limit our maximum priority, which will break
# this test. Instead, we test in order of increasing priority,
# and match either the expected value or the highest so far.
highest_prio = None
for prio in [psutil.IDLE_PRIORITY_CLASS,
psutil.BELOW_NORMAL_PRIORITY_CLASS,
Expand All @@ -855,10 +853,16 @@ def test_nice(self):
pass
else:
new_prio = p.nice()
if CI_TESTING:
# The OS may limit our maximum priority,
# even if the function succeeds. For higher
# priorities, we match either the expected
# value or the highest so far.
if prio in (psutil.ABOVE_NORMAL_PRIORITY_CLASS,
psutil.HIGH_PRIORITY_CLASS,
psutil.REALTIME_PRIORITY_CLASS):
if new_prio == prio or highest_prio is None:
highest_prio = prio
self.assertEqual(new_prio, highest_prio)
self.assertEqual(new_prio, highest_prio)
else:
self.assertEqual(new_prio, prio)
else:
Expand Down
38 changes: 22 additions & 16 deletions psutil/tests/test_system.py
Original file line number Diff line number Diff line change
Expand Up @@ -212,19 +212,20 @@ 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 # noqa
user.host # noqa
assert user.started > 0.0, user
datetime.datetime.fromtimestamp(user.started)
if WINDOWS or OPENBSD:
self.assertIsNone(user.pid)
else:
psutil.Process(user.pid)
with self.subTest(user=user):
assert user.name
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 # noqa
user.host # noqa
self.assertGreater(user.started, 0.0)
datetime.datetime.fromtimestamp(user.started)
if WINDOWS or OPENBSD:
self.assertIsNone(user.pid)
else:
psutil.Process(user.pid)

def test_test(self):
# test for psutil.test() function
Expand Down Expand Up @@ -434,15 +435,20 @@ def test_per_cpu_times_2(self):
if difference >= 0.05:
return

@unittest.skipIf(CI_TESTING and OPENBSD, "unreliable on OPENBSD + CI")
def test_cpu_times_comparison(self):
# Make sure the sum of all per cpu times is almost equal to
# base "one cpu" times.
# base "one cpu" times. On OpenBSD the sum of per-CPUs is
# higher for some reason.
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)
with self.subTest(field=field, base=base, per_cpu=per_cpu):
self.assertAlmostEqual(
getattr(base, field),
getattr(summed_values, field),
delta=1)

def _test_cpu_percent(self, percent, last_ret, new_ret):
try:
Expand Down
29 changes: 22 additions & 7 deletions psutil/tests/test_unicode.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@
from psutil import POSIX
from psutil import WINDOWS
from psutil._compat import PY3
from psutil._compat import super
from psutil._compat import u
from psutil.tests import APPVEYOR
from psutil.tests import ASCII_FS
Expand Down Expand Up @@ -158,10 +159,18 @@ def try_unicode(suffix):
class BaseUnicodeTest(PsutilTestCase):
funky_suffix = None

@classmethod
def setUpClass(cls):
super().setUpClass()
cls.skip_tests = False
if cls.funky_suffix is not None:
if not try_unicode(cls.funky_suffix):
cls.skip_tests = True

def setUp(self):
if self.funky_suffix is not None:
if not try_unicode(self.funky_suffix):
raise self.skipTest("can't handle unicode str")
super().setUp()
if self.skip_tests:
raise self.skipTest("can't handle unicode str")


@serialrun
Expand All @@ -174,11 +183,13 @@ class TestFSAPIs(BaseUnicodeTest):

@classmethod
def setUpClass(cls):
super().setUpClass()
cls.funky_name = get_testfn(suffix=cls.funky_suffix)
create_exe(cls.funky_name)

@classmethod
def tearDownClass(cls):
super().tearDownClass()
safe_rmpath(cls.funky_name)

def expect_exact_path_match(self):
Expand All @@ -192,7 +203,8 @@ def expect_exact_path_match(self):
# ---

def test_proc_exe(self):
subp = self.spawn_testproc(cmd=[self.funky_name])
cmd = [self.funky_name, "-c", "time.sleep(10)"]
subp = self.spawn_testproc(cmd)
p = psutil.Process(subp.pid)
exe = p.exe()
self.assertIsInstance(exe, str)
Expand All @@ -201,20 +213,23 @@ def test_proc_exe(self):
os.path.normcase(self.funky_name))

def test_proc_name(self):
subp = self.spawn_testproc(cmd=[self.funky_name])
cmd = [self.funky_name, "-c", "time.sleep(10)"]
subp = self.spawn_testproc(cmd)
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 = self.spawn_testproc(cmd=[self.funky_name])
cmd = [self.funky_name, "-c", "time.sleep(10)"]
subp = self.spawn_testproc(cmd)
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])
self.assertEqual(
cmdline, [self.funky_name, "-c", "time.sleep(10)"])

def test_proc_cwd(self):
dname = self.funky_name + "2"
Expand Down
5 changes: 3 additions & 2 deletions scripts/internal/winmake.py
Original file line number Diff line number Diff line change
Expand Up @@ -442,7 +442,7 @@ def test_by_name(name):
sh("%s -m unittest -v %s" % (PYTHON, name))


def test_failed():
def test_last_failed():
"""Re-run tests which failed on last run."""
build()
sh("%s %s --last-failed" % (PYTHON, RUNNER_PY))
Expand Down Expand Up @@ -559,7 +559,8 @@ def parse_args():
test_by_name = sp.add_parser('test-by-name', help="<ARG> run test by name")
sp.add_parser('test-connections', help="run connections tests")
sp.add_parser('test-contracts', help="run contracts tests")
sp.add_parser('test-failed', help="re-run tests which failed on last run")
sp.add_parser('test-last-failed',
help="re-run tests which failed on last run")
sp.add_parser('test-memleaks', help="run memory leaks tests")
sp.add_parser('test-misc', help="run misc tests")
sp.add_parser('test-platform', help="run windows only tests")
Expand Down

0 comments on commit c677cb1

Please sign in to comment.