Skip to content

Commit

Permalink
Merge branch 'master' of github.com:giampaolo/psutil
Browse files Browse the repository at this point in the history
  • Loading branch information
giampaolo committed Oct 20, 2017
2 parents 2fd5679 + 548656a commit dd80a8b
Show file tree
Hide file tree
Showing 6 changed files with 37 additions and 23 deletions.
1 change: 0 additions & 1 deletion IDEAS
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ PLATFORMS
=========

- #355: Android (with patch)
- #605: AIX (with branch)
- #82: Cygwin (PR at #998)
- #276: GNU/Hurd
- #693: Windows Nano
Expand Down
4 changes: 0 additions & 4 deletions psutil/TODO.aix
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,3 @@ Known limitations:
reading basic process info may fail or return incorrect values when process is starting
(see IBM APAR IV58499 - fixed in newer AIX versions)
sockets and pipes may not be counted in num_fds (fixed in newer AIX versions)

The following unit tests may fail:
test_prog_w_funky_name funky name tests don't work, name is truncated
test_cmdline long args are cut from cmdline in /proc/pid/psinfo and getargs
3 changes: 2 additions & 1 deletion psutil/_psutil_windows.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include <wtsapi32.h>
#include <Winsvc.h>
#include <PowrProf.h>
#include <signal.h>

// Link with Iphlpapi.lib
#pragma comment(lib, "IPHLPAPI.lib")
Expand Down Expand Up @@ -349,7 +350,7 @@ psutil_proc_kill(PyObject *self, PyObject *args) {
}

// kill the process
if (! TerminateProcess(hProcess, 0)) {
if (! TerminateProcess(hProcess, SIGTERM)) {
err = GetLastError();
// See: https://github.com/giampaolo/psutil/issues/1099
if (err != ERROR_ACCESS_DENIED) {
Expand Down
3 changes: 2 additions & 1 deletion psutil/tests/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -690,7 +690,7 @@ def create_exe(outpath, c_code=None):
if c_code:
if not which("gcc"):
raise ValueError("gcc is not installed")
if c_code is None:
if isinstance(c_code, bool): # c_code is True
c_code = textwrap.dedent(
"""
#include <unistd.h>
Expand All @@ -699,6 +699,7 @@ def create_exe(outpath, c_code=None):
return 1;
}
""")
assert isinstance(c_code, str), c_code
with tempfile.NamedTemporaryFile(
suffix='.c', delete=False, mode='wt') as f:
f.write(c_code)
Expand Down
35 changes: 25 additions & 10 deletions psutil/tests/test_posix.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ def ps(cmd):
if not LINUX:
cmd = cmd.replace(" --no-headers ", " ")
if SUNOS:
cmd = cmd.replace("-o command", "-o comm")
cmd = cmd.replace("-o start", "-o stime")
if AIX:
cmd = cmd.replace("-o rss", "-o rssize")
Expand All @@ -59,6 +58,28 @@ def ps(cmd):
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):
Expand Down Expand Up @@ -124,9 +145,7 @@ def test_vsz_memory(self):
self.assertEqual(vsz_ps, vsz_psutil)

def test_name(self):
# use command + arg since "comm" keyword not supported on all platforms
name_ps = ps("ps --no-headers -o command -p %s" % (
self.pid)).split(' ')[0]
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()
Expand Down Expand Up @@ -182,8 +201,7 @@ def test_create_time(self):
self.assertIn(time_ps, [time_psutil_tstamp, round_time_psutil_tstamp])

def test_exe(self):
ps_pathname = ps("ps --no-headers -o command -p %s" %
self.pid).split(' ')[0]
ps_pathname = ps_name(self.pid)
psutil_pathname = psutil.Process(self.pid).exe()
try:
self.assertEqual(ps_pathname, psutil_pathname)
Expand All @@ -198,11 +216,8 @@ def test_exe(self):
self.assertEqual(ps_pathname, adjusted_ps_pathname)

def test_cmdline(self):
ps_cmdline = ps("ps --no-headers -o command -p %s" % self.pid)
ps_cmdline = ps_args(self.pid)
psutil_cmdline = " ".join(psutil.Process(self.pid).cmdline())
if SUNOS:
# ps on Solaris only shows the first part of the cmdline
psutil_cmdline = psutil_cmdline.split(" ")[0]
self.assertEqual(ps_cmdline, psutil_cmdline)

# On SUNOS "ps" reads niceness /proc/pid/psinfo which returns an
Expand Down
14 changes: 8 additions & 6 deletions psutil/tests/test_process.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ def test_wait(self):
if POSIX:
self.assertEqual(code, -signal.SIGKILL)
else:
self.assertEqual(code, 0)
self.assertEqual(code, signal.SIGTERM)
self.assertFalse(p.is_running())

sproc = get_test_subprocess()
Expand All @@ -161,7 +161,7 @@ def test_wait(self):
if POSIX:
self.assertEqual(code, -signal.SIGTERM)
else:
self.assertEqual(code, 0)
self.assertEqual(code, signal.SIGTERM)
self.assertFalse(p.is_running())

# check sys.exit() code
Expand Down Expand Up @@ -207,8 +207,8 @@ def test_wait_non_children(self):
# to get None.
self.assertEqual(ret2, None)
else:
self.assertEqual(ret1, 0)
self.assertEqual(ret1, 0)
self.assertEqual(ret1, signal.SIGTERM)
self.assertEqual(ret1, signal.SIGTERM)

def test_wait_timeout_0(self):
sproc = get_test_subprocess()
Expand All @@ -227,7 +227,7 @@ def test_wait_timeout_0(self):
if POSIX:
self.assertEqual(code, -signal.SIGKILL)
else:
self.assertEqual(code, 0)
self.assertEqual(code, signal.SIGTERM)
self.assertFalse(p.is_running())

def test_cpu_percent(self):
Expand Down Expand Up @@ -724,7 +724,8 @@ def test_cmdline(self):
# and Open BSD returns a truncated string.
# Also /proc/pid/cmdline behaves the same so it looks
# like this is a kernel bug.
if NETBSD or OPENBSD:
# XXX - AIX truncates long arguments in /proc/pid/cmdline
if NETBSD or OPENBSD or AIX:
self.assertEqual(
psutil.Process(sproc.pid).cmdline()[0], PYTHON)
else:
Expand All @@ -738,6 +739,7 @@ def test_name(self):

# 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:
Expand Down

0 comments on commit dd80a8b

Please sign in to comment.