diff options
| author | Giampaolo Rodola <g.rodola@gmail.com> | 2017-04-29 09:28:13 +0200 |
|---|---|---|
| committer | Giampaolo Rodola <g.rodola@gmail.com> | 2017-04-29 09:28:13 +0200 |
| commit | 319e2fd4f54c6cc1bc2f9f9c8990d8b18593f82e (patch) | |
| tree | 276c1ddd075ffec93cfde2faab56e8a7ceea4989 | |
| parent | 7e6afb20d5d7b0fe2028125ba9924dab28e9976c (diff) | |
| download | psutil-319e2fd4f54c6cc1bc2f9f9c8990d8b18593f82e.tar.gz | |
add a test case which exposes #1013 on FreeBSD
| -rw-r--r-- | psutil/_compat.py | 49 | ||||
| -rw-r--r-- | psutil/tests/__init__.py | 1 | ||||
| -rw-r--r-- | psutil/tests/test_connections.py | 37 | ||||
| -rw-r--r-- | psutil/tests/test_unicode.py | 31 |
4 files changed, 93 insertions, 25 deletions
diff --git a/psutil/_compat.py b/psutil/_compat.py index de91638f..5777c38d 100644 --- a/psutil/_compat.py +++ b/psutil/_compat.py @@ -5,6 +5,7 @@ """Module which provides compatibility with older Python versions.""" import collections +import contextlib import functools import os import sys @@ -247,3 +248,51 @@ except ImportError: if _access_check(name, mode): return name return None + + +# A backport of contextlib.nested for Python 3. +nested = getattr(contextlib, "nested") +if nested is None: + @contextlib.contextmanager + def nested(*managers): + """Support multiple context managers in a single with-statement. + + Code like this: + + with nested(A, B, C) as (X, Y, Z): + <body> + + is equivalent to this: + + with A as X: + with B as Y: + with C as Z: + <body> + + """ + exits = [] + vars = [] + exc = (None, None, None) + try: + for mgr in managers: + exit = mgr.__exit__ + enter = mgr.__enter__ + vars.append(enter()) + exits.append(exit) + yield vars + except: # NOQA + exc = sys.exc_info() + finally: + while exits: + exit = exits.pop() + try: + if exit(*exc): + exc = (None, None, None) + except: # NOQA + exc = sys.exc_info() + if exc != (None, None, None): + # Don't rely on sys.exc_info() still containing + # the right information. Another exception may + # have been raised and caught by an exit method + # exc[1] already has the __traceback__ attribute populated + raise exc[1] diff --git a/psutil/tests/__init__.py b/psutil/tests/__init__.py index 99cc30a9..36ac713c 100644 --- a/psutil/tests/__init__.py +++ b/psutil/tests/__init__.py @@ -923,7 +923,6 @@ def check_connection_ntuple(conn): if err.errno != errno.EADDRNOTAVAIL: raise elif conn.family == AF_UNIX: - assert not conn.raddr, repr(conn.raddr) assert conn.status == psutil.CONN_NONE, conn.status # check type diff --git a/psutil/tests/test_connections.py b/psutil/tests/test_connections.py index 18759c0d..8b67768e 100644 --- a/psutil/tests/test_connections.py +++ b/psutil/tests/test_connections.py @@ -10,7 +10,6 @@ import os import socket import textwrap from contextlib import closing -from contextlib import nested from socket import AF_INET from socket import AF_INET6 from socket import SOCK_DGRAM @@ -23,6 +22,7 @@ from psutil import POSIX from psutil import SUNOS from psutil import WINDOWS from psutil._common import supports_ipv6 +from psutil._compat import nested from psutil._compat import unicode from psutil.tests import AF_UNIX from psutil.tests import bind_socket @@ -38,6 +38,7 @@ from psutil.tests import skip_on_access_denied from psutil.tests import TESTFN from psutil.tests import unittest from psutil.tests import unix_socket_path +from psutil.tests import unix_socketpair from psutil.tests import wait_for_file @@ -174,14 +175,25 @@ class TestConnectedSocketPairs(Base, unittest.TestCase): """ @staticmethod - def differentiate_tcp_socks(cons, server_addr): + def distinguish_tcp_socks(cons, server_addr): """Given a list of connections return a (server, client) - tuple. + connection ntuple. """ if cons[0].laddr == server_addr: return (cons[0], cons[1]) else: - assert cons[1].laddr == server_addr + assert cons[1].laddr == server_addr, (cons, server_addr) + return (cons[1], cons[0]) + + @staticmethod + def distinguish_unix_socks(cons): + """Given a list of connections and 2 sockets return a + (server, client) connection ntuple. + """ + if cons[0].laddr: + return (cons[0], cons[1]) + else: + assert cons[1].laddr, cons return (cons[1], cons[0]) def test_tcp(self): @@ -189,7 +201,7 @@ class TestConnectedSocketPairs(Base, unittest.TestCase): server, client = inet_socketpair(AF_INET, SOCK_STREAM, addr=addr) with nested(closing(server), closing(client)): cons = psutil.Process().connections(kind='all') - server_conn, client_conn = self.differentiate_tcp_socks(cons, addr) + server_conn, client_conn = self.distinguish_tcp_socks(cons, addr) self.check_socket(server, conn=server_conn) self.check_socket(client, conn=client_conn) self.assertEqual(server_conn.status, psutil.CONN_ESTABLISHED) @@ -201,6 +213,21 @@ class TestConnectedSocketPairs(Base, unittest.TestCase): # self.assertEqual(len(cons), 1) # self.assertEqual(cons[0].status, psutil.CONN_CLOSE_WAIT) + def test_unix(self): + with unix_socket_path() as name: + server, client = unix_socketpair(name) + with nested(closing(server), closing(client)): + cons = psutil.Process().connections(kind='unix') + self.assertEqual(len(cons), 2) + server_conn, client_conn = self.distinguish_unix_socks(cons) + self.check_socket(server, conn=server_conn) + self.check_socket(client, conn=client_conn) + self.assertEqual(server_conn.laddr, name) + # TODO: https://github.com/giampaolo/psutil/issues/1035 + self.assertIn(server_conn.raddr, ("", None)) + # TODO: https://github.com/giampaolo/psutil/issues/1035 + self.assertIn(client_conn.laddr, ("", None)) + @skip_on_access_denied(only_if=OSX) def test_combos(self): def check_conn(proc, conn, family, type, laddr, raddr, status, kinds): diff --git a/psutil/tests/test_unicode.py b/psutil/tests/test_unicode.py index c212ccf6..571f4cc9 100644 --- a/psutil/tests/test_unicode.py +++ b/psutil/tests/test_unicode.py @@ -54,7 +54,6 @@ https://github.com/giampaolo/psutil/issues/655#issuecomment-136131180 import os import socket from contextlib import closing -from contextlib import nested from psutil import BSD from psutil import OSX @@ -76,7 +75,6 @@ from psutil.tests import TESTFN_UNICODE from psutil.tests import TRAVIS from psutil.tests import unittest from psutil.tests import unix_socket_path -from psutil.tests import unix_socketpair import psutil import psutil.tests @@ -156,22 +154,18 @@ class _BaseFSAPIsTests(object): @unittest.skipUnless(hasattr(socket, "AF_UNIX"), "AF_UNIX not supported") def test_proc_connections(self): - with unix_socket_path( - suffix=os.path.basename(self.funky_name)) as name: + suffix = os.path.basename(self.funky_name) + with unix_socket_path(suffix=suffix) as name: try: - server, client = unix_socketpair(name) + sock = bind_unix_socket(name) except UnicodeEncodeError: if PY3: raise else: raise unittest.SkipTest("not supported") - with nested(closing(server), closing(client)): - cons = psutil.Process().connections(kind='unix') - self.assertEqual(len(cons), 2) - cmap = dict([(x.fd, x) for x in cons]) - self.assertEqual(cmap[server.fileno()].laddr, name) - if cmap[client.fileno()].laddr: - self.assertEqual(cmap[client.fileno()].laddr, name) + with closing(sock): + conn = psutil.Process().connections('unix')[0] + self.assertEqual(conn.laddr, name) @unittest.skipUnless(hasattr(socket, "AF_UNIX"), "AF_UNIX not supported") @skip_on_access_denied() @@ -182,8 +176,8 @@ class _BaseFSAPIsTests(object): return conn raise ValueError("connection not found") - with unix_socket_path( - suffix=os.path.basename(self.funky_name)) as name: + suffix = os.path.basename(self.funky_name) + with unix_socket_path(suffix=suffix) as name: try: sock = bind_unix_socket(name) except UnicodeEncodeError: @@ -191,11 +185,10 @@ class _BaseFSAPIsTests(object): raise else: raise unittest.SkipTest("not supported") - self.addCleanup(safe_rmpath, name) - self.addCleanup(sock.close) - cons = psutil.net_connections(kind='unix') - conn = find_sock(cons) - self.assertEqual(conn.laddr, name) + with closing(sock): + cons = psutil.net_connections(kind='unix') + conn = find_sock(cons) + self.assertEqual(conn.laddr, name) def test_disk_usage(self): safe_mkdir(self.funky_name) |
