test_osx.py 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. #!/usr/bin/env python3
  2. # Copyright (c) 2009, Giampaolo Rodola'. All rights reserved.
  3. # Use of this source code is governed by a BSD-style license that can be
  4. # found in the LICENSE file.
  5. """macOS specific tests."""
  6. import platform
  7. import re
  8. import time
  9. import unittest
  10. import psutil
  11. from psutil import MACOS
  12. from psutil import POSIX
  13. from psutil.tests import HAS_BATTERY
  14. from psutil.tests import TOLERANCE_DISK_USAGE
  15. from psutil.tests import TOLERANCE_SYS_MEM
  16. from psutil.tests import PsutilTestCase
  17. from psutil.tests import retry_on_failure
  18. from psutil.tests import sh
  19. from psutil.tests import spawn_testproc
  20. from psutil.tests import terminate
  21. if POSIX:
  22. from psutil._psutil_posix import getpagesize
  23. def sysctl(cmdline):
  24. """Expects a sysctl command with an argument and parse the result
  25. returning only the value of interest.
  26. """
  27. out = sh(cmdline)
  28. result = out.split()[1]
  29. try:
  30. return int(result)
  31. except ValueError:
  32. return result
  33. def vm_stat(field):
  34. """Wrapper around 'vm_stat' cmdline utility."""
  35. out = sh('vm_stat')
  36. for line in out.split('\n'):
  37. if field in line:
  38. break
  39. else:
  40. raise ValueError("line not found")
  41. return int(re.search(r'\d+', line).group(0)) * getpagesize()
  42. @unittest.skipIf(not MACOS, "MACOS only")
  43. class TestProcess(PsutilTestCase):
  44. @classmethod
  45. def setUpClass(cls):
  46. cls.pid = spawn_testproc().pid
  47. @classmethod
  48. def tearDownClass(cls):
  49. terminate(cls.pid)
  50. def test_process_create_time(self):
  51. output = sh("ps -o lstart -p %s" % self.pid)
  52. start_ps = output.replace('STARTED', '').strip()
  53. hhmmss = start_ps.split(' ')[-2]
  54. year = start_ps.split(' ')[-1]
  55. start_psutil = psutil.Process(self.pid).create_time()
  56. self.assertEqual(
  57. hhmmss,
  58. time.strftime("%H:%M:%S", time.localtime(start_psutil)))
  59. self.assertEqual(
  60. year,
  61. time.strftime("%Y", time.localtime(start_psutil)))
  62. @unittest.skipIf(not MACOS, "MACOS only")
  63. class TestSystemAPIs(PsutilTestCase):
  64. # --- disk
  65. @retry_on_failure()
  66. def test_disks(self):
  67. # test psutil.disk_usage() and psutil.disk_partitions()
  68. # against "df -a"
  69. def df(path):
  70. out = sh('df -k "%s"' % path).strip()
  71. lines = out.split('\n')
  72. lines.pop(0)
  73. line = lines.pop(0)
  74. dev, total, used, free = line.split()[:4]
  75. if dev == 'none':
  76. dev = ''
  77. total = int(total) * 1024
  78. used = int(used) * 1024
  79. free = int(free) * 1024
  80. return dev, total, used, free
  81. for part in psutil.disk_partitions(all=False):
  82. usage = psutil.disk_usage(part.mountpoint)
  83. dev, total, used, free = df(part.mountpoint)
  84. self.assertEqual(part.device, dev)
  85. self.assertEqual(usage.total, total)
  86. self.assertAlmostEqual(usage.free, free,
  87. delta=TOLERANCE_DISK_USAGE)
  88. self.assertAlmostEqual(usage.used, used,
  89. delta=TOLERANCE_DISK_USAGE)
  90. # --- cpu
  91. def test_cpu_count_logical(self):
  92. num = sysctl("sysctl hw.logicalcpu")
  93. self.assertEqual(num, psutil.cpu_count(logical=True))
  94. def test_cpu_count_cores(self):
  95. num = sysctl("sysctl hw.physicalcpu")
  96. self.assertEqual(num, psutil.cpu_count(logical=False))
  97. # TODO: remove this once 1892 is fixed
  98. @unittest.skipIf(platform.machine() == 'arm64', "skipped due to #1892")
  99. def test_cpu_freq(self):
  100. freq = psutil.cpu_freq()
  101. self.assertEqual(
  102. freq.current * 1000 * 1000, sysctl("sysctl hw.cpufrequency"))
  103. self.assertEqual(
  104. freq.min * 1000 * 1000, sysctl("sysctl hw.cpufrequency_min"))
  105. self.assertEqual(
  106. freq.max * 1000 * 1000, sysctl("sysctl hw.cpufrequency_max"))
  107. # --- virtual mem
  108. def test_vmem_total(self):
  109. sysctl_hwphymem = sysctl('sysctl hw.memsize')
  110. self.assertEqual(sysctl_hwphymem, psutil.virtual_memory().total)
  111. @retry_on_failure()
  112. def test_vmem_free(self):
  113. vmstat_val = vm_stat("free")
  114. psutil_val = psutil.virtual_memory().free
  115. self.assertAlmostEqual(psutil_val, vmstat_val, delta=TOLERANCE_SYS_MEM)
  116. @retry_on_failure()
  117. def test_vmem_active(self):
  118. vmstat_val = vm_stat("active")
  119. psutil_val = psutil.virtual_memory().active
  120. self.assertAlmostEqual(psutil_val, vmstat_val, delta=TOLERANCE_SYS_MEM)
  121. @retry_on_failure()
  122. def test_vmem_inactive(self):
  123. vmstat_val = vm_stat("inactive")
  124. psutil_val = psutil.virtual_memory().inactive
  125. self.assertAlmostEqual(psutil_val, vmstat_val, delta=TOLERANCE_SYS_MEM)
  126. @retry_on_failure()
  127. def test_vmem_wired(self):
  128. vmstat_val = vm_stat("wired")
  129. psutil_val = psutil.virtual_memory().wired
  130. self.assertAlmostEqual(psutil_val, vmstat_val, delta=TOLERANCE_SYS_MEM)
  131. # --- swap mem
  132. @retry_on_failure()
  133. def test_swapmem_sin(self):
  134. vmstat_val = vm_stat("Pageins")
  135. psutil_val = psutil.swap_memory().sin
  136. self.assertAlmostEqual(psutil_val, vmstat_val, delta=TOLERANCE_SYS_MEM)
  137. @retry_on_failure()
  138. def test_swapmem_sout(self):
  139. vmstat_val = vm_stat("Pageout")
  140. psutil_val = psutil.swap_memory().sout
  141. self.assertAlmostEqual(psutil_val, vmstat_val, delta=TOLERANCE_SYS_MEM)
  142. # --- network
  143. def test_net_if_stats(self):
  144. for name, stats in psutil.net_if_stats().items():
  145. try:
  146. out = sh("ifconfig %s" % name)
  147. except RuntimeError:
  148. pass
  149. else:
  150. self.assertEqual(stats.isup, 'RUNNING' in out, msg=out)
  151. self.assertEqual(stats.mtu,
  152. int(re.findall(r'mtu (\d+)', out)[0]))
  153. # --- sensors_battery
  154. @unittest.skipIf(not HAS_BATTERY, "no battery")
  155. def test_sensors_battery(self):
  156. out = sh("pmset -g batt")
  157. percent = re.search(r"(\d+)%", out).group(1)
  158. drawing_from = re.search("Now drawing from '([^']+)'", out).group(1)
  159. power_plugged = drawing_from == "AC Power"
  160. psutil_result = psutil.sensors_battery()
  161. self.assertEqual(psutil_result.power_plugged, power_plugged)
  162. self.assertEqual(psutil_result.percent, int(percent))
  163. if __name__ == '__main__':
  164. from psutil.tests.runner import run_from_name
  165. run_from_name(__file__)