summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGiampaolo Rodola <g.rodola@gmail.com>2023-04-11 12:04:03 +0200
committerGitHub <noreply@github.com>2023-04-11 12:04:03 +0200
commit90b35e3ae85651d67a095205adc94aaa0a4ec98f (patch)
treeb5fc6d89af3f3f4dac14f84576f7a34f3d4ae6fe
parentf11c0552f2bcfc8bc3afa35d29adb4dc5525c092 (diff)
downloadpsutil-90b35e3ae85651d67a095205adc94aaa0a4ec98f.tar.gz
[POSIX] psutil.users() loses precision for "started" attribute #2225 (#2226)
-rw-r--r--.github/workflows/issues.py2
-rw-r--r--HISTORY.rst2
-rw-r--r--psutil/_psutil_aix.c4
-rw-r--r--psutil/_psutil_bsd.c4
-rw-r--r--psutil/_psutil_linux.c4
-rw-r--r--psutil/_psutil_osx.c4
-rw-r--r--psutil/_psutil_sunos.c4
-rwxr-xr-xpsutil/tests/test_posix.py40
8 files changed, 47 insertions, 17 deletions
diff --git a/.github/workflows/issues.py b/.github/workflows/issues.py
index 06438b97..77a9bc96 100644
--- a/.github/workflows/issues.py
+++ b/.github/workflows/issues.py
@@ -59,7 +59,7 @@ LABELS_MAP = {
"wsl": ["wsl"],
"unix": [
"psposix", "_psutil_posix", "waitpid", "statvfs", "/dev/tty",
- "/dev/pts",
+ "/dev/pts", "posix",
],
"pypy": ["pypy"],
# types
diff --git a/HISTORY.rst b/HISTORY.rst
index a86f56c4..ac50e897 100644
--- a/HISTORY.rst
+++ b/HISTORY.rst
@@ -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
=====
diff --git a/psutil/_psutil_aix.c b/psutil/_psutil_aix.c
index f5c5cc66..8a1b8de9 100644
--- a/psutil/_psutil_aix.c
+++ b/psutil/_psutil_aix.c
@@ -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
);
diff --git a/psutil/_psutil_bsd.c b/psutil/_psutil_bsd.c
index 1ffa7b00..c2de7c91 100644
--- a/psutil/_psutil_bsd.c
+++ b/psutil/_psutil_bsd.c
@@ -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
diff --git a/psutil/_psutil_linux.c b/psutil/_psutil_linux.c
index 924fe702..a6ee6025 100644
--- a/psutil/_psutil_linux.c
+++ b/psutil/_psutil_linux.c
@@ -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
);
diff --git a/psutil/_psutil_osx.c b/psutil/_psutil_osx.c
index ab43871f..ed29b33b 100644
--- a/psutil/_psutil_osx.c
+++ b/psutil/_psutil_osx.c
@@ -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) {
diff --git a/psutil/_psutil_sunos.c b/psutil/_psutil_sunos.c
index 84bf1c40..e2e7c018 100644
--- a/psutil/_psutil_sunos.c
+++ b/psutil/_psutil_sunos.c
@@ -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
);
diff --git a/psutil/tests/test_posix.py b/psutil/tests/test_posix.py
index 0dc1dfda..a37899fd 100755
--- a/psutil/tests/test_posix.py
+++ b/psutil/tests/test_posix.py
@@ -23,7 +23,6 @@ from psutil import MACOS
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
@@ -334,19 +333,48 @@ class TestSystemAPIs(PsutilTestCase):
"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