You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			322 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Python
		
	
			
		
		
	
	
			322 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Python
		
	
| #!/usr/bin/env python3
 | |
| 
 | |
| # Copyright (c) 2009, Giampaolo Rodola'. All rights reserved.
 | |
| # Use of this source code is governed by a BSD-style license that can be
 | |
| # found in the LICENSE file.
 | |
| 
 | |
| """Contracts tests. These tests mainly check API sanity in terms of
 | |
| returned types and APIs availability.
 | |
| Some of these are duplicates of tests test_system.py and test_process.py.
 | |
| """
 | |
| 
 | |
| import signal
 | |
| 
 | |
| import psutil
 | |
| from psutil import AIX
 | |
| from psutil import FREEBSD
 | |
| from psutil import LINUX
 | |
| from psutil import MACOS
 | |
| from psutil import NETBSD
 | |
| from psutil import OPENBSD
 | |
| from psutil import POSIX
 | |
| from psutil import SUNOS
 | |
| from psutil import WINDOWS
 | |
| from psutil.tests import AARCH64
 | |
| from psutil.tests import GITHUB_ACTIONS
 | |
| from psutil.tests import HAS_CPU_FREQ
 | |
| from psutil.tests import HAS_NET_IO_COUNTERS
 | |
| from psutil.tests import HAS_SENSORS_FANS
 | |
| from psutil.tests import HAS_SENSORS_TEMPERATURES
 | |
| from psutil.tests import SKIP_SYSCONS
 | |
| from psutil.tests import PsutilTestCase
 | |
| from psutil.tests import create_sockets
 | |
| from psutil.tests import enum
 | |
| from psutil.tests import is_namedtuple
 | |
| from psutil.tests import kernel_version
 | |
| from psutil.tests import pytest
 | |
| 
 | |
| # ===================================================================
 | |
| # --- APIs availability
 | |
| # ===================================================================
 | |
| 
 | |
| # Make sure code reflects what doc promises in terms of APIs
 | |
| # availability.
 | |
| 
 | |
| 
 | |
| class TestAvailConstantsAPIs(PsutilTestCase):
 | |
|     def test_PROCFS_PATH(self):
 | |
|         assert hasattr(psutil, "PROCFS_PATH") == (LINUX or SUNOS or AIX)
 | |
| 
 | |
|     def test_win_priority(self):
 | |
|         assert hasattr(psutil, "ABOVE_NORMAL_PRIORITY_CLASS") == WINDOWS
 | |
|         assert hasattr(psutil, "BELOW_NORMAL_PRIORITY_CLASS") == WINDOWS
 | |
|         assert hasattr(psutil, "HIGH_PRIORITY_CLASS") == WINDOWS
 | |
|         assert hasattr(psutil, "IDLE_PRIORITY_CLASS") == WINDOWS
 | |
|         assert hasattr(psutil, "NORMAL_PRIORITY_CLASS") == WINDOWS
 | |
|         assert hasattr(psutil, "REALTIME_PRIORITY_CLASS") == WINDOWS
 | |
| 
 | |
|     def test_linux_ioprio_linux(self):
 | |
|         assert hasattr(psutil, "IOPRIO_CLASS_NONE") == LINUX
 | |
|         assert hasattr(psutil, "IOPRIO_CLASS_RT") == LINUX
 | |
|         assert hasattr(psutil, "IOPRIO_CLASS_BE") == LINUX
 | |
|         assert hasattr(psutil, "IOPRIO_CLASS_IDLE") == LINUX
 | |
| 
 | |
|     def test_linux_ioprio_windows(self):
 | |
|         assert hasattr(psutil, "IOPRIO_HIGH") == WINDOWS
 | |
|         assert hasattr(psutil, "IOPRIO_NORMAL") == WINDOWS
 | |
|         assert hasattr(psutil, "IOPRIO_LOW") == WINDOWS
 | |
|         assert hasattr(psutil, "IOPRIO_VERYLOW") == WINDOWS
 | |
| 
 | |
|     @pytest.mark.skipif(
 | |
|         GITHUB_ACTIONS and LINUX,
 | |
|         reason="unsupported on GITHUB_ACTIONS + LINUX",
 | |
|     )
 | |
|     def test_rlimit(self):
 | |
|         assert hasattr(psutil, "RLIM_INFINITY") == LINUX or FREEBSD
 | |
|         assert hasattr(psutil, "RLIMIT_AS") == LINUX or FREEBSD
 | |
|         assert hasattr(psutil, "RLIMIT_CORE") == LINUX or FREEBSD
 | |
|         assert hasattr(psutil, "RLIMIT_CPU") == LINUX or FREEBSD
 | |
|         assert hasattr(psutil, "RLIMIT_DATA") == LINUX or FREEBSD
 | |
|         assert hasattr(psutil, "RLIMIT_FSIZE") == LINUX or FREEBSD
 | |
|         assert hasattr(psutil, "RLIMIT_MEMLOCK") == LINUX or FREEBSD
 | |
|         assert hasattr(psutil, "RLIMIT_NOFILE") == LINUX or FREEBSD
 | |
|         assert hasattr(psutil, "RLIMIT_NPROC") == LINUX or FREEBSD
 | |
|         assert hasattr(psutil, "RLIMIT_RSS") == LINUX or FREEBSD
 | |
|         assert hasattr(psutil, "RLIMIT_STACK") == LINUX or FREEBSD
 | |
| 
 | |
|         assert hasattr(psutil, "RLIMIT_LOCKS") == LINUX
 | |
|         if POSIX:
 | |
|             if kernel_version() >= (2, 6, 8):
 | |
|                 assert hasattr(psutil, "RLIMIT_MSGQUEUE") == LINUX
 | |
|             if kernel_version() >= (2, 6, 12):
 | |
|                 assert hasattr(psutil, "RLIMIT_NICE") == LINUX
 | |
|             if kernel_version() >= (2, 6, 12):
 | |
|                 assert hasattr(psutil, "RLIMIT_RTPRIO") == LINUX
 | |
|             if kernel_version() >= (2, 6, 25):
 | |
|                 assert hasattr(psutil, "RLIMIT_RTTIME") == LINUX
 | |
|             if kernel_version() >= (2, 6, 8):
 | |
|                 assert hasattr(psutil, "RLIMIT_SIGPENDING") == LINUX
 | |
| 
 | |
|         assert hasattr(psutil, "RLIMIT_SWAP") == FREEBSD
 | |
|         assert hasattr(psutil, "RLIMIT_SBSIZE") == FREEBSD
 | |
|         assert hasattr(psutil, "RLIMIT_NPTS") == FREEBSD
 | |
| 
 | |
| 
 | |
| class TestAvailSystemAPIs(PsutilTestCase):
 | |
|     def test_win_service_iter(self):
 | |
|         assert hasattr(psutil, "win_service_iter") == WINDOWS
 | |
| 
 | |
|     def test_win_service_get(self):
 | |
|         assert hasattr(psutil, "win_service_get") == WINDOWS
 | |
| 
 | |
|     @pytest.mark.skipif(MACOS and AARCH64, reason="skipped due to #1892")
 | |
|     def test_cpu_freq(self):
 | |
|         assert hasattr(psutil, "cpu_freq") == (
 | |
|             LINUX or MACOS or WINDOWS or FREEBSD or OPENBSD
 | |
|         )
 | |
| 
 | |
|     def test_sensors_temperatures(self):
 | |
|         assert hasattr(psutil, "sensors_temperatures") == (LINUX or FREEBSD)
 | |
| 
 | |
|     def test_sensors_fans(self):
 | |
|         assert hasattr(psutil, "sensors_fans") == LINUX
 | |
| 
 | |
|     def test_battery(self):
 | |
|         assert hasattr(psutil, "sensors_battery") == (
 | |
|             LINUX or WINDOWS or FREEBSD or MACOS
 | |
|         )
 | |
| 
 | |
| 
 | |
| class TestAvailProcessAPIs(PsutilTestCase):
 | |
|     def test_environ(self):
 | |
|         assert hasattr(psutil.Process, "environ") == (
 | |
|             LINUX
 | |
|             or MACOS
 | |
|             or WINDOWS
 | |
|             or AIX
 | |
|             or SUNOS
 | |
|             or FREEBSD
 | |
|             or OPENBSD
 | |
|             or NETBSD
 | |
|         )
 | |
| 
 | |
|     def test_uids(self):
 | |
|         assert hasattr(psutil.Process, "uids") == POSIX
 | |
| 
 | |
|     def test_gids(self):
 | |
|         assert hasattr(psutil.Process, "uids") == POSIX
 | |
| 
 | |
|     def test_terminal(self):
 | |
|         assert hasattr(psutil.Process, "terminal") == POSIX
 | |
| 
 | |
|     def test_ionice(self):
 | |
|         assert hasattr(psutil.Process, "ionice") == (LINUX or WINDOWS)
 | |
| 
 | |
|     @pytest.mark.skipif(
 | |
|         GITHUB_ACTIONS and LINUX,
 | |
|         reason="unsupported on GITHUB_ACTIONS + LINUX",
 | |
|     )
 | |
|     def test_rlimit(self):
 | |
|         assert hasattr(psutil.Process, "rlimit") == (LINUX or FREEBSD)
 | |
| 
 | |
|     def test_io_counters(self):
 | |
|         hasit = hasattr(psutil.Process, "io_counters")
 | |
|         assert hasit == (not (MACOS or SUNOS))
 | |
| 
 | |
|     def test_num_fds(self):
 | |
|         assert hasattr(psutil.Process, "num_fds") == POSIX
 | |
| 
 | |
|     def test_num_handles(self):
 | |
|         assert hasattr(psutil.Process, "num_handles") == WINDOWS
 | |
| 
 | |
|     def test_cpu_affinity(self):
 | |
|         assert hasattr(psutil.Process, "cpu_affinity") == (
 | |
|             LINUX or WINDOWS or FREEBSD
 | |
|         )
 | |
| 
 | |
|     def test_cpu_num(self):
 | |
|         assert hasattr(psutil.Process, "cpu_num") == (
 | |
|             LINUX or FREEBSD or SUNOS
 | |
|         )
 | |
| 
 | |
|     def test_memory_maps(self):
 | |
|         hasit = hasattr(psutil.Process, "memory_maps")
 | |
|         assert hasit == (not (OPENBSD or NETBSD or AIX or MACOS))
 | |
| 
 | |
| 
 | |
| # ===================================================================
 | |
| # --- API types
 | |
| # ===================================================================
 | |
| 
 | |
| 
 | |
| class TestSystemAPITypes(PsutilTestCase):
 | |
|     """Check the return types of system related APIs.
 | |
|     https://github.com/giampaolo/psutil/issues/1039.
 | |
|     """
 | |
| 
 | |
|     @classmethod
 | |
|     def setUpClass(cls):
 | |
|         cls.proc = psutil.Process()
 | |
| 
 | |
|     def assert_ntuple_of_nums(self, nt, type_=float, gezero=True):
 | |
|         assert is_namedtuple(nt)
 | |
|         for n in nt:
 | |
|             assert isinstance(n, type_)
 | |
|             if gezero:
 | |
|                 assert n >= 0
 | |
| 
 | |
|     def test_cpu_times(self):
 | |
|         self.assert_ntuple_of_nums(psutil.cpu_times())
 | |
|         for nt in psutil.cpu_times(percpu=True):
 | |
|             self.assert_ntuple_of_nums(nt)
 | |
| 
 | |
|     def test_cpu_percent(self):
 | |
|         assert isinstance(psutil.cpu_percent(interval=None), float)
 | |
|         assert isinstance(psutil.cpu_percent(interval=0.00001), float)
 | |
| 
 | |
|     def test_cpu_times_percent(self):
 | |
|         self.assert_ntuple_of_nums(psutil.cpu_times_percent(interval=None))
 | |
|         self.assert_ntuple_of_nums(psutil.cpu_times_percent(interval=0.0001))
 | |
| 
 | |
|     def test_cpu_count(self):
 | |
|         assert isinstance(psutil.cpu_count(), int)
 | |
| 
 | |
|     # TODO: remove this once 1892 is fixed
 | |
|     @pytest.mark.skipif(MACOS and AARCH64, reason="skipped due to #1892")
 | |
|     @pytest.mark.skipif(not HAS_CPU_FREQ, reason="not supported")
 | |
|     def test_cpu_freq(self):
 | |
|         if psutil.cpu_freq() is None:
 | |
|             raise pytest.skip("cpu_freq() returns None")
 | |
|         self.assert_ntuple_of_nums(psutil.cpu_freq(), type_=(float, int))
 | |
| 
 | |
|     def test_disk_io_counters(self):
 | |
|         # Duplicate of test_system.py. Keep it anyway.
 | |
|         for k, v in psutil.disk_io_counters(perdisk=True).items():
 | |
|             assert isinstance(k, str)
 | |
|             self.assert_ntuple_of_nums(v, type_=int)
 | |
| 
 | |
|     def test_disk_partitions(self):
 | |
|         # Duplicate of test_system.py. Keep it anyway.
 | |
|         for disk in psutil.disk_partitions():
 | |
|             assert isinstance(disk.device, str)
 | |
|             assert isinstance(disk.mountpoint, str)
 | |
|             assert isinstance(disk.fstype, str)
 | |
|             assert isinstance(disk.opts, str)
 | |
| 
 | |
|     @pytest.mark.skipif(SKIP_SYSCONS, reason="requires root")
 | |
|     def test_net_connections(self):
 | |
|         with create_sockets():
 | |
|             ret = psutil.net_connections('all')
 | |
|             assert len(ret) == len(set(ret))
 | |
|             for conn in ret:
 | |
|                 assert is_namedtuple(conn)
 | |
| 
 | |
|     def test_net_if_addrs(self):
 | |
|         # Duplicate of test_system.py. Keep it anyway.
 | |
|         for ifname, addrs in psutil.net_if_addrs().items():
 | |
|             assert isinstance(ifname, str)
 | |
|             for addr in addrs:
 | |
|                 assert isinstance(addr.family, enum.IntEnum)
 | |
|                 assert isinstance(addr.address, str)
 | |
|                 assert isinstance(addr.netmask, (str, type(None)))
 | |
|                 assert isinstance(addr.broadcast, (str, type(None)))
 | |
| 
 | |
|     def test_net_if_stats(self):
 | |
|         # Duplicate of test_system.py. Keep it anyway.
 | |
|         for ifname, info in psutil.net_if_stats().items():
 | |
|             assert isinstance(ifname, str)
 | |
|             assert isinstance(info.isup, bool)
 | |
|             assert isinstance(info.duplex, enum.IntEnum)
 | |
|             assert isinstance(info.speed, int)
 | |
|             assert isinstance(info.mtu, int)
 | |
| 
 | |
|     @pytest.mark.skipif(not HAS_NET_IO_COUNTERS, reason="not supported")
 | |
|     def test_net_io_counters(self):
 | |
|         # Duplicate of test_system.py. Keep it anyway.
 | |
|         for ifname in psutil.net_io_counters(pernic=True):
 | |
|             assert isinstance(ifname, str)
 | |
| 
 | |
|     @pytest.mark.skipif(not HAS_SENSORS_FANS, reason="not supported")
 | |
|     def test_sensors_fans(self):
 | |
|         # Duplicate of test_system.py. Keep it anyway.
 | |
|         for name, units in psutil.sensors_fans().items():
 | |
|             assert isinstance(name, str)
 | |
|             for unit in units:
 | |
|                 assert isinstance(unit.label, str)
 | |
|                 assert isinstance(unit.current, (float, int, type(None)))
 | |
| 
 | |
|     @pytest.mark.skipif(not HAS_SENSORS_TEMPERATURES, reason="not supported")
 | |
|     def test_sensors_temperatures(self):
 | |
|         # Duplicate of test_system.py. Keep it anyway.
 | |
|         for name, units in psutil.sensors_temperatures().items():
 | |
|             assert isinstance(name, str)
 | |
|             for unit in units:
 | |
|                 assert isinstance(unit.label, str)
 | |
|                 assert isinstance(unit.current, (float, int, type(None)))
 | |
|                 assert isinstance(unit.high, (float, int, type(None)))
 | |
|                 assert isinstance(unit.critical, (float, int, type(None)))
 | |
| 
 | |
|     def test_boot_time(self):
 | |
|         # Duplicate of test_system.py. Keep it anyway.
 | |
|         assert isinstance(psutil.boot_time(), float)
 | |
| 
 | |
|     def test_users(self):
 | |
|         # Duplicate of test_system.py. Keep it anyway.
 | |
|         for user in psutil.users():
 | |
|             assert isinstance(user.name, str)
 | |
|             assert isinstance(user.terminal, (str, type(None)))
 | |
|             assert isinstance(user.host, (str, type(None)))
 | |
|             assert isinstance(user.pid, (int, type(None)))
 | |
|             if isinstance(user.pid, int):
 | |
|                 assert user.pid > 0
 | |
| 
 | |
| 
 | |
| class TestProcessWaitType(PsutilTestCase):
 | |
|     @pytest.mark.skipif(not POSIX, reason="not POSIX")
 | |
|     def test_negative_signal(self):
 | |
|         p = psutil.Process(self.spawn_subproc().pid)
 | |
|         p.terminate()
 | |
|         code = p.wait()
 | |
|         assert code == -signal.SIGTERM
 | |
|         assert isinstance(code, enum.IntEnum)
 |