Skip to content

Commit

Permalink
[POSIX] psutil.users() loses precision for "started" attribute #2225 (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
giampaolo authored Apr 11, 2023
1 parent f11c055 commit 90b35e3
Show file tree
Hide file tree
Showing 8 changed files with 47 additions and 17 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/issues.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@
"wsl": ["wsl"],
"unix": [
"psposix", "_psutil_posix", "waitpid", "statvfs", "/dev/tty",
"/dev/pts",
"/dev/pts", "posix",
],
"pypy": ["pypy"],
# types
Expand Down
2 changes: 2 additions & 0 deletions HISTORY.rst
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
argument.
- 2216_, [Windows]: fix tests when running in a virtual environment (patch by
Matthieu Darbois)
- 2225_, [POSIX]: `users()`_ loses precision for ``started`` attribute (off by
1 minute).

5.9.4
=====
Expand Down
4 changes: 2 additions & 2 deletions psutil/_psutil_aix.c
Original file line number Diff line number Diff line change
Expand Up @@ -497,11 +497,11 @@ psutil_users(PyObject *self, PyObject *args) {
if (! py_hostname)
goto error;
py_tuple = Py_BuildValue(
"(OOOfOi)",
"(OOOdOi)",
py_username, // username
py_tty, // tty
py_hostname, // hostname
(float)ut->ut_tv.tv_sec, // tstamp
(double)ut->ut_tv.tv_sec, // tstamp
py_user_proc, // (bool) user process
ut->ut_pid // process id
);
Expand Down
4 changes: 2 additions & 2 deletions psutil/_psutil_bsd.c
Original file line number Diff line number Diff line change
Expand Up @@ -966,11 +966,11 @@ psutil_users(PyObject *self, PyObject *args) {
if (! py_hostname)
goto error;
py_tuple = Py_BuildValue(
"(OOOfi)",
"(OOOdi)",
py_username, // username
py_tty, // tty
py_hostname, // hostname
(float)ut.ut_time, // start time
(double)ut.ut_time, // start time
#if defined(PSUTIL_OPENBSD) || (defined(__FreeBSD_version) && __FreeBSD_version < 900000)
-1 // process id (set to None later)
#else
Expand Down
4 changes: 2 additions & 2 deletions psutil/_psutil_linux.c
Original file line number Diff line number Diff line change
Expand Up @@ -392,11 +392,11 @@ psutil_users(PyObject *self, PyObject *args) {
goto error;

py_tuple = Py_BuildValue(
"OOOfO" _Py_PARSE_PID,
"OOOdO" _Py_PARSE_PID,
py_username, // username
py_tty, // tty
py_hostname, // hostname
(float)ut->ut_tv.tv_sec, // tstamp
(double)ut->ut_tv.tv_sec, // tstamp
py_user_proc, // (bool) user process
ut->ut_pid // process id
);
Expand Down
4 changes: 2 additions & 2 deletions psutil/_psutil_osx.c
Original file line number Diff line number Diff line change
Expand Up @@ -1579,11 +1579,11 @@ psutil_users(PyObject *self, PyObject *args) {
if (! py_hostname)
goto error;
py_tuple = Py_BuildValue(
"(OOOfi)",
"(OOOdi)",
py_username, // username
py_tty, // tty
py_hostname, // hostname
(float)utx->ut_tv.tv_sec, // start time
(double)utx->ut_tv.tv_sec, // start time
utx->ut_pid // process id
);
if (!py_tuple) {
Expand Down
4 changes: 2 additions & 2 deletions psutil/_psutil_sunos.c
Original file line number Diff line number Diff line change
Expand Up @@ -647,11 +647,11 @@ psutil_users(PyObject *self, PyObject *args) {
if (! py_hostname)
goto error;
py_tuple = Py_BuildValue(
"(OOOfOi)",
"(OOOdOi)",
py_username, // username
py_tty, // tty
py_hostname, // hostname
(float)ut->ut_tv.tv_sec, // tstamp
(double)ut->ut_tv.tv_sec, // tstamp
py_user_proc, // (bool) user process
ut->ut_pid // process id
);
Expand Down
40 changes: 34 additions & 6 deletions psutil/tests/test_posix.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
from psutil import OPENBSD
from psutil import POSIX
from psutil import SUNOS
from psutil.tests import CI_TESTING
from psutil.tests import HAS_NET_IO_COUNTERS
from psutil.tests import PYTHON_EXE
from psutil.tests import PsutilTestCase
Expand Down Expand Up @@ -334,19 +333,48 @@ def test_nic_names(self):
"couldn't find %s nic in 'ifconfig -a' output\n%s" % (
nic, output))

@unittest.skipIf(CI_TESTING and not psutil.users(), "unreliable on CI")
# @unittest.skipIf(CI_TESTING and not psutil.users(), "unreliable on CI")
@retry_on_failure()
def test_users(self):
out = sh("who")
out = sh("who -u")
if not out.strip():
raise self.skipTest("no users on this system")
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)
with self.subTest(psutil=psutil.users(), who=out):
for idx, u in enumerate(psutil.users()):
self.assertEqual(u.name, users[idx])
self.assertEqual(u.terminal, terminals[idx])
p = psutil.Process(u.pid)
# on macOS time is off by ~47 secs for some reason, but
# the next test against 'who' CLI succeeds
delta = 60 if MACOS else 1
self.assertAlmostEqual(u.started, p.create_time(), delta=delta)

@retry_on_failure()
def test_users_started(self):
out = sh("who -u")
if not out.strip():
raise self.skipTest("no users on this system")
# '2023-04-11 09:31' (Linux)
started = re.findall(r"\d\d\d\d-\d\d-\d\d \d\d:\d\d", out)
if started:
tstamp = "%Y-%m-%d %H:%M"
else:
# 'Apr 10 22:27' (macOS)
started = re.findall(r"[A-Z][a-z][a-z] \d\d \d\d:\d\d", out)
if started:
tstamp = "%b %d %H:%M"
else:
raise ValueError(
"cannot interpret tstamp in who output\n%s" % (out))
with self.subTest(psutil=psutil.users(), who=out):
for idx, u in enumerate(psutil.users()):
psutil_value = datetime.datetime.fromtimestamp(
u.started).strftime(tstamp)
self.assertEqual(psutil_value, started[idx])

def test_pid_exists_let_raise(self):
# According to "man 2 kill" possible error values for kill
Expand Down

0 comments on commit 90b35e3

Please sign in to comment.