class BSDSpecificTestCase(unittest.TestCase): """Generic tests common to all BSD variants.""" @classmethod def setUpClass(cls): cls.pid = get_test_subprocess().pid @classmethod def tearDownClass(cls): reap_children() def test_process_create_time(self): cmdline = "ps -o lstart -p %s" % self.pid p = subprocess.Popen(cmdline, shell=1, stdout=subprocess.PIPE) output = p.communicate()[0] if PY3: output = str(output, sys.stdout.encoding) start_ps = output.replace('STARTED', '').strip() start_psutil = psutil.Process(self.pid).create_time() start_psutil = time.strftime("%a %b %e %H:%M:%S %Y", time.localtime(start_psutil)) self.assertEqual(start_ps, start_psutil) def test_disks(self): # test psutil.disk_usage() and psutil.disk_partitions() # against "df -a" def df(path): out = sh('df -k "%s"' % path).strip() lines = out.split('\n') lines.pop(0) line = lines.pop(0) dev, total, used, free = line.split()[:4] if dev == 'none': dev = '' total = int(total) * 1024 used = int(used) * 1024 free = int(free) * 1024 return dev, total, used, free for part in psutil.disk_partitions(all=False): usage = psutil.disk_usage(part.mountpoint) dev, total, used, free = df(part.mountpoint) self.assertEqual(part.device, dev) self.assertEqual(usage.total, total) # 10 MB tollerance if abs(usage.free - free) > 10 * 1024 * 1024: self.fail("psutil=%s, df=%s" % (usage.free, free)) if abs(usage.used - used) > 10 * 1024 * 1024: self.fail("psutil=%s, df=%s" % (usage.used, used)) @unittest.skipIf(not which('sysctl'), "sysctl cmd not available") def test_cpu_count_logical(self): syst = sysctl("hw.ncpu") self.assertEqual(psutil.cpu_count(logical=True), syst) @unittest.skipIf(not which('sysctl'), "sysctl cmd not available") def test_virtual_memory_total(self): num = sysctl('hw.physmem') self.assertEqual(num, psutil.virtual_memory().total)
class TestSystemNetwork(unittest.TestCase): def test_net_if_addrs_ips(self): for name, addrs in psutil.net_if_addrs().items(): for addr in addrs: if addr.family == psutil.AF_LINK: self.assertEqual(addr.address, get_mac_address(name)) elif addr.family == socket.AF_INET: self.assertEqual(addr.address, get_ipv4_address(name)) # TODO: test for AF_INET6 family @unittest.skipUnless(which('ip'), "'ip' utility not available") @unittest.skipIf(TRAVIS, "skipped on Travis") def test_net_if_names(self): out = sh("ip addr").strip() nics = [x for x in psutil.net_if_addrs().keys() if ':' not in x] found = 0 for line in out.split('\n'): line = line.strip() if re.search("^\d+:", line): found += 1 name = line.split(':')[1].strip() self.assertIn(name, nics) self.assertEqual(len(nics), found, msg="%s\n---\n%s" % (pprint.pformat(nics), out)) @mock.patch('psutil._pslinux.socket.inet_ntop', side_effect=ValueError) @mock.patch('psutil._pslinux.supports_ipv6', return_value=False) def test_net_connections_ipv6_unsupported(self, supports_ipv6, inet_ntop): # see: https://github.com/giampaolo/psutil/issues/623 try: s = socket.socket(socket.AF_INET6, socket.SOCK_STREAM) self.addCleanup(s.close) s.bind(("::1", 0)) except socket.error: pass psutil.net_connections(kind='inet6') def test_net_connections_mocked(self): def open_mock(name, *args, **kwargs): if name == '/proc/net/unix': return io.StringIO( textwrap.dedent(u"""\ 0: 00000003 000 000 0001 03 462170 @/tmp/dbus-Qw2hMPIU3n 0: 00000003 000 000 0001 03 35010 @/tmp/dbus-tB2X8h69BQ 0: 00000003 000 000 0001 03 34424 @/tmp/dbus-cHy80Y8O 000000000000000000000000000000000000000000000000000000 """)) else: return orig_open(name, *args, **kwargs) return orig_open(name, *args) orig_open = open patch_point = 'builtins.open' if PY3 else '__builtin__.open' with mock.patch(patch_point, side_effect=open_mock) as m: psutil.net_connections(kind='unix') assert m.called
class TestSystemNetwork(unittest.TestCase): def test_net_if_addrs_ips(self): for name, addrs in psutil.net_if_addrs().items(): for addr in addrs: if addr.family == psutil.AF_LINK: self.assertEqual(addr.address, get_mac_address(name)) elif addr.family == socket.AF_INET: self.assertEqual(addr.address, get_ipv4_address(name)) # TODO: test for AF_INET6 family @unittest.skipUnless(which('ip'), "'ip' utility not available") @unittest.skipIf(TRAVIS, "skipped on Travis") def test_net_if_names(self): out = sh("ip addr").strip() nics = [x for x in psutil.net_if_addrs().keys() if ':' not in x] found = 0 for line in out.split('\n'): line = line.strip() if re.search("^\d+:", line): found += 1 name = line.split(':')[1].strip() self.assertIn(name, nics) self.assertEqual(len(nics), found, msg="%s\n---\n%s" % ( pprint.pformat(nics), out)) @mock.patch('psutil._pslinux.socket.inet_ntop', side_effect=ValueError) @mock.patch('psutil._pslinux.supports_ipv6', return_value=False) def test_net_connections_ipv6_unsupported(self, supports_ipv6, inet_ntop): # see: https://github.com/giampaolo/psutil/issues/623 try: s = socket.socket(socket.AF_INET6, socket.SOCK_STREAM) self.addCleanup(s.close) s.bind(("::1", 0)) except socket.error: pass psutil.net_connections(kind='inet6')
from psutil import OPENBSD from psutil._compat import PY3 from psutil.tests import get_test_subprocess from psutil.tests import MEMORY_TOLERANCE from psutil.tests import reap_children from psutil.tests import retry_before_failing from psutil.tests import run_test_module_by_name from psutil.tests import sh from psutil.tests import unittest from psutil.tests import which if BSD: PAGESIZE = os.sysconf("SC_PAGE_SIZE") if os.getuid() == 0: # muse requires root privileges MUSE_AVAILABLE = which('muse') else: MUSE_AVAILABLE = False else: MUSE_AVAILABLE = False def sysctl(cmdline): """Expects a sysctl command with an argument and parse the result returning only the value of interest. """ result = sh("sysctl " + cmdline) if FREEBSD: result = result[result.find(": ") + 2:] elif OPENBSD or NETBSD: result = result[result.find("=") + 1:]
class TestSystemAPIs(unittest.TestCase): """Test some system APIs.""" @retry_before_failing() def test_pids(self): # Note: this test might fail if the OS is starting/killing # other processes in the meantime if SUNOS or AIX: cmd = ["ps", "-A", "-o", "pid"] else: cmd = ["ps", "ax", "-o", "pid"] p = get_test_subprocess(cmd, stdout=subprocess.PIPE) output = p.communicate()[0].strip() assert p.poll() == 0 if PY3: output = str(output, sys.stdout.encoding) pids_ps = [] for line in output.split('\n')[1:]: if line: pid = int(line.split()[0].strip()) pids_ps.append(pid) # remove ps subprocess pid which is supposed to be dead in meantime pids_ps.remove(p.pid) pids_psutil = psutil.pids() pids_ps.sort() pids_psutil.sort() # on OSX and OPENBSD ps doesn't show pid 0 if OSX or OPENBSD and 0 not in pids_ps: pids_ps.insert(0, 0) if pids_ps != pids_psutil: difference = [x for x in pids_psutil if x not in pids_ps] + \ [x for x in pids_ps if x not in pids_psutil] self.fail("difference: " + str(difference)) # for some reason ifconfig -a does not report all interfaces # returned by psutil @unittest.skipIf(SUNOS, "unreliable on SUNOS") @unittest.skipIf(TRAVIS, "unreliable on TRAVIS") @unittest.skipIf(not which('ifconfig'), "no ifconfig cmd") def test_nic_names(self): output = sh("ifconfig -a") for nic in psutil.net_io_counters(pernic=True).keys(): for line in output.split(): if line.startswith(nic): break else: self.fail("couldn't find %s nic in 'ifconfig -a' output\n%s" % (nic, output)) # can't find users on APPVEYOR or TRAVIS @unittest.skipIf(APPVEYOR or TRAVIS and not psutil.users(), "unreliable on APPVEYOR or TRAVIS") @retry_before_failing() def test_users(self): out = sh("who") 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) def test_pid_exists_let_raise(self): # According to "man 2 kill" possible error values for kill # are (EINVAL, EPERM, ESRCH). Test that any other errno # results in an exception. with mock.patch("psutil._psposix.os.kill", side_effect=OSError(errno.EBADF, "")) as m: self.assertRaises(OSError, psutil._psposix.pid_exists, os.getpid()) assert m.called def test_os_waitpid_let_raise(self): # os.waitpid() is supposed to catch EINTR and ECHILD only. # Test that any other errno results in an exception. with mock.patch("psutil._psposix.os.waitpid", side_effect=OSError(errno.EBADF, "")) as m: self.assertRaises(OSError, psutil._psposix.wait_pid, os.getpid()) assert m.called def test_os_waitpid_eintr(self): # os.waitpid() is supposed to "retry" on EINTR. with mock.patch("psutil._psposix.os.waitpid", side_effect=OSError(errno.EINTR, "")) as m: self.assertRaises(psutil._psposix.TimeoutExpired, psutil._psposix.wait_pid, os.getpid(), timeout=0.01) assert m.called def test_os_waitpid_bad_ret_status(self): # Simulate os.waitpid() returning a bad status. with mock.patch("psutil._psposix.os.waitpid", return_value=(1, -1)) as m: self.assertRaises(ValueError, psutil._psposix.wait_pid, os.getpid()) assert m.called # AIX can return '-' in df output instead of numbers, e.g. for /proc @unittest.skipIf(AIX, "unreliable on AIX") def test_disk_usage(self): def df(device): out = sh("df -k %s" % device).strip() line = out.split('\n')[1] fields = line.split() total = int(fields[1]) * 1024 used = int(fields[2]) * 1024 free = int(fields[3]) * 1024 percent = float(fields[4].replace('%', '')) return (total, used, free, percent) tolerance = 4 * 1024 * 1024 # 4MB for part in psutil.disk_partitions(all=False): usage = psutil.disk_usage(part.mountpoint) try: total, used, free, percent = df(part.device) except RuntimeError as err: # see: # https://travis-ci.org/giampaolo/psutil/jobs/138338464 # https://travis-ci.org/giampaolo/psutil/jobs/138343361 err = str(err).lower() if "no such file or directory" in err or \ "raw devices not supported" in err or \ "permission denied" in err: continue else: raise else: self.assertAlmostEqual(usage.total, total, delta=tolerance) self.assertAlmostEqual(usage.used, used, delta=tolerance) self.assertAlmostEqual(usage.free, free, delta=tolerance) self.assertAlmostEqual(usage.percent, percent, delta=1)
class TestSystemCPU(unittest.TestCase): @unittest.skipIf(TRAVIS, "unknown failure on travis") def test_cpu_times(self): fields = psutil.cpu_times()._fields kernel_ver = re.findall('\d+\.\d+\.\d+', os.uname()[2])[0] kernel_ver_info = tuple(map(int, kernel_ver.split('.'))) if kernel_ver_info >= (2, 6, 11): self.assertIn('steal', fields) else: self.assertNotIn('steal', fields) if kernel_ver_info >= (2, 6, 24): self.assertIn('guest', fields) else: self.assertNotIn('guest', fields) if kernel_ver_info >= (3, 2, 0): self.assertIn('guest_nice', fields) else: self.assertNotIn('guest_nice', fields) @unittest.skipUnless(which("nproc"), "nproc utility not available") def test_cpu_count_logical_w_nproc(self): num = int(sh("nproc --all")) self.assertEqual(psutil.cpu_count(logical=True), num) @unittest.skipUnless(which("lscpu"), "lscpu utility not available") def test_cpu_count_logical_w_lscpu(self): out = sh("lscpu -p") num = len([x for x in out.split('\n') if not x.startswith('#')]) self.assertEqual(psutil.cpu_count(logical=True), num) def test_cpu_count_logical_mocked(self): import psutil._pslinux original = psutil._pslinux.cpu_count_logical() # Here we want to mock os.sysconf("SC_NPROCESSORS_ONLN") in # order to cause the parsing of /proc/cpuinfo and /proc/stat. with mock.patch('psutil._pslinux.os.sysconf', side_effect=ValueError) as m: self.assertEqual(psutil._pslinux.cpu_count_logical(), original) assert m.called # Let's have open() return emtpy data and make sure None is # returned ('cause we mimick os.cpu_count()). with mock.patch('psutil._pslinux.open', create=True) as m: self.assertIsNone(psutil._pslinux.cpu_count_logical()) self.assertEqual(m.call_count, 2) # /proc/stat should be the last one self.assertEqual(m.call_args[0][0], '/proc/stat') # Let's push this a bit further and make sure /proc/cpuinfo # parsing works as expected. with open('/proc/cpuinfo', 'rb') as f: cpuinfo_data = f.read() fake_file = io.BytesIO(cpuinfo_data) with mock.patch('psutil._pslinux.open', return_value=fake_file, create=True) as m: self.assertEqual(psutil._pslinux.cpu_count_logical(), original) # Finally, let's make /proc/cpuinfo return meaningless data; # this way we'll fall back on relying on /proc/stat def open_mock(name, *args, **kwargs): if name.startswith('/proc/cpuinfo'): return io.BytesIO(b"") else: return orig_open(name, *args, **kwargs) orig_open = open patch_point = 'builtins.open' if PY3 else '__builtin__.open' with mock.patch(patch_point, side_effect=open_mock, create=True): self.assertEqual(psutil._pslinux.cpu_count_logical(), original) def test_cpu_count_physical_mocked(self): # Have open() return emtpy data and make sure None is returned # ('cause we want to mimick os.cpu_count()) with mock.patch('psutil._pslinux.open', create=True) as m: self.assertIsNone(psutil._pslinux.cpu_count_physical()) assert m.called
class BSDSpecificTestCase(unittest.TestCase): """Generic tests common to all BSD variants.""" @classmethod def setUpClass(cls): cls.pid = get_test_subprocess().pid @classmethod def tearDownClass(cls): reap_children() @unittest.skipIf(NETBSD, "-o lstart doesn't work on NETBSD") def test_process_create_time(self): output = sh("ps -o lstart -p %s" % self.pid) start_ps = output.replace('STARTED', '').strip() start_psutil = psutil.Process(self.pid).create_time() start_psutil = time.strftime("%a %b %e %H:%M:%S %Y", time.localtime(start_psutil)) self.assertEqual(start_ps, start_psutil) def test_disks(self): # test psutil.disk_usage() and psutil.disk_partitions() # against "df -a" def df(path): out = sh('df -k "%s"' % path).strip() lines = out.split('\n') lines.pop(0) line = lines.pop(0) dev, total, used, free = line.split()[:4] if dev == 'none': dev = '' total = int(total) * 1024 used = int(used) * 1024 free = int(free) * 1024 return dev, total, used, free for part in psutil.disk_partitions(all=False): usage = psutil.disk_usage(part.mountpoint) dev, total, used, free = df(part.mountpoint) self.assertEqual(part.device, dev) self.assertEqual(usage.total, total) # 10 MB tollerance if abs(usage.free - free) > 10 * 1024 * 1024: self.fail("psutil=%s, df=%s" % (usage.free, free)) if abs(usage.used - used) > 10 * 1024 * 1024: self.fail("psutil=%s, df=%s" % (usage.used, used)) @unittest.skipIf(not which('sysctl'), "sysctl cmd not available") def test_cpu_count_logical(self): syst = sysctl("hw.ncpu") self.assertEqual(psutil.cpu_count(logical=True), syst) @unittest.skipIf(not which('sysctl'), "sysctl cmd not available") def test_virtual_memory_total(self): num = sysctl('hw.physmem') self.assertEqual(num, psutil.virtual_memory().total) def test_net_if_stats(self): for name, stats in psutil.net_if_stats().items(): try: out = sh("ifconfig %s" % name) except RuntimeError: pass else: self.assertEqual(stats.isup, 'RUNNING' in out, msg=out) if "mtu" in out: self.assertEqual(stats.mtu, int(re.findall(r'mtu (\d+)', out)[0]))
class TestSystemNetwork(unittest.TestCase): def test_net_if_addrs_ips(self): for name, addrs in psutil.net_if_addrs().items(): for addr in addrs: if addr.family == psutil.AF_LINK: self.assertEqual(addr.address, get_mac_address(name)) elif addr.family == socket.AF_INET: self.assertEqual(addr.address, get_ipv4_address(name)) # TODO: test for AF_INET6 family def test_net_if_stats(self): for name, stats in psutil.net_if_stats().items(): try: out = sh("ifconfig %s" % name) except RuntimeError: pass else: self.assertEqual(stats.isup, 'RUNNING' in out, msg=out) self.assertEqual(stats.mtu, int(re.findall('MTU:(\d+)', out)[0])) def test_net_io_counters(self): def ifconfig(nic): ret = {} out = sh("ifconfig %s" % name) ret['packets_recv'] = int(re.findall('RX packets:(\d+)', out)[0]) ret['packets_sent'] = int(re.findall('TX packets:(\d+)', out)[0]) ret['errin'] = int(re.findall('errors:(\d+)', out)[0]) ret['errout'] = int(re.findall('errors:(\d+)', out)[1]) ret['dropin'] = int(re.findall('dropped:(\d+)', out)[0]) ret['dropout'] = int(re.findall('dropped:(\d+)', out)[1]) ret['bytes_recv'] = int(re.findall('RX bytes:(\d+)', out)[0]) ret['bytes_sent'] = int(re.findall('TX bytes:(\d+)', out)[0]) return ret for name, stats in psutil.net_io_counters(pernic=True).items(): try: ifconfig_ret = ifconfig(name) except RuntimeError: continue self.assertAlmostEqual( stats.bytes_recv, ifconfig_ret['bytes_recv'], delta=1024) self.assertAlmostEqual( stats.bytes_sent, ifconfig_ret['bytes_sent'], delta=1024) self.assertAlmostEqual( stats.packets_recv, ifconfig_ret['packets_recv'], delta=512) self.assertAlmostEqual( stats.packets_sent, ifconfig_ret['packets_sent'], delta=512) self.assertAlmostEqual( stats.errin, ifconfig_ret['errin'], delta=10) self.assertAlmostEqual( stats.errout, ifconfig_ret['errout'], delta=10) self.assertAlmostEqual( stats.dropin, ifconfig_ret['dropin'], delta=10) self.assertAlmostEqual( stats.dropout, ifconfig_ret['dropout'], delta=10) @unittest.skipUnless(which('ip'), "'ip' utility not available") @unittest.skipIf(TRAVIS, "skipped on Travis") def test_net_if_names(self): out = sh("ip addr").strip() nics = [x for x in psutil.net_if_addrs().keys() if ':' not in x] found = 0 for line in out.split('\n'): line = line.strip() if re.search("^\d+:", line): found += 1 name = line.split(':')[1].strip() self.assertIn(name, nics) self.assertEqual(len(nics), found, msg="%s\n---\n%s" % ( pprint.pformat(nics), out)) @mock.patch('psutil._pslinux.socket.inet_ntop', side_effect=ValueError) @mock.patch('psutil._pslinux.supports_ipv6', return_value=False) def test_net_connections_ipv6_unsupported(self, supports_ipv6, inet_ntop): # see: https://github.com/giampaolo/psutil/issues/623 try: s = socket.socket(socket.AF_INET6, socket.SOCK_STREAM) self.addCleanup(s.close) s.bind(("::1", 0)) except socket.error: pass psutil.net_connections(kind='inet6') def test_net_connections_mocked(self): def open_mock(name, *args, **kwargs): if name == '/proc/net/unix': return io.StringIO(textwrap.dedent(u"""\ 0: 00000003 000 000 0001 03 462170 @/tmp/dbus-Qw2hMPIU3n 0: 00000003 000 000 0001 03 35010 @/tmp/dbus-tB2X8h69BQ 0: 00000003 000 000 0001 03 34424 @/tmp/dbus-cHy80Y8O 000000000000000000000000000000000000000000000000000000 """)) else: return orig_open(name, *args, **kwargs) orig_open = open patch_point = 'builtins.open' if PY3 else '__builtin__.open' with mock.patch(patch_point, side_effect=open_mock) as m: psutil.net_connections(kind='unix') assert m.called
from psutil import OPENBSD from psutil.tests import HAS_BATTERY from psutil.tests import TOLERANCE_SYS_MEM from psutil.tests import PsutilTestCase from psutil.tests import retry_on_failure from psutil.tests import sh from psutil.tests import spawn_testproc from psutil.tests import terminate from psutil.tests import which if BSD: from psutil._psutil_posix import getpagesize PAGESIZE = getpagesize() # muse requires root privileges MUSE_AVAILABLE = True if os.getuid() == 0 and which('muse') else False else: PAGESIZE = None MUSE_AVAILABLE = False def sysctl(cmdline): """Expects a sysctl command with an argument and parse the result returning only the value of interest. """ result = sh("sysctl " + cmdline) if FREEBSD: result = result[result.find(": ") + 2:] elif OPENBSD or NETBSD: result = result[result.find("=") + 1:] try: