test_sudo.py 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  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. """Tests which are meant to be run as root.
  6. NOTE: keep this module compatible with unittest: we want to run this
  7. file with the unittest runner, since pytest may not be installed for
  8. the root user.
  9. """
  10. import datetime
  11. import time
  12. import unittest
  13. import psutil
  14. from psutil import FREEBSD
  15. from psutil import LINUX
  16. from psutil import OPENBSD
  17. from psutil import WINDOWS
  18. from psutil.tests import CI_TESTING
  19. from psutil.tests import PsutilTestCase
  20. def get_systime():
  21. if hasattr(time, "clock_gettime") and hasattr(time, "CLOCK_REALTIME"):
  22. return time.clock_gettime(time.CLOCK_REALTIME)
  23. return time.time()
  24. def set_systime(secs): # secs since the epoch
  25. if hasattr(time, "clock_settime") and hasattr(time, "CLOCK_REALTIME"):
  26. try:
  27. time.clock_settime(time.CLOCK_REALTIME, secs)
  28. except PermissionError:
  29. raise unittest.SkipTest("needs root")
  30. elif WINDOWS:
  31. import pywintypes
  32. import win32api
  33. dt = datetime.datetime.fromtimestamp(secs, datetime.timezone.utc)
  34. try:
  35. win32api.SetSystemTime(
  36. dt.year,
  37. dt.month,
  38. dt.isoweekday() % 7,
  39. dt.day,
  40. dt.hour,
  41. dt.minute,
  42. dt.second,
  43. int(dt.microsecond / 1000),
  44. )
  45. except pywintypes.error as err:
  46. if err.winerror == 1314:
  47. raise unittest.SkipTest("needs Administrator user")
  48. raise
  49. else:
  50. raise unittest.SkipTest("setting systime not supported")
  51. class TestUpdatedSystemTime(PsutilTestCase):
  52. """Tests which update the system clock."""
  53. def setUp(self):
  54. self.time_updated = False
  55. self.orig_time = get_systime()
  56. self.time_started = time.monotonic()
  57. def tearDown(self):
  58. if self.time_updated:
  59. extra_t = time.monotonic() - self.time_started
  60. set_systime(self.orig_time + extra_t)
  61. def update_systime(self):
  62. # set system time 1 hour later
  63. set_systime(self.orig_time + 3600)
  64. self.time_updated = True
  65. def test_boot_time(self):
  66. # Test that boot_time() reflects system clock updates.
  67. t1 = psutil.boot_time()
  68. self.update_systime()
  69. t2 = psutil.boot_time()
  70. self.assertGreater(t2, t1)
  71. diff = int(t2 - t1)
  72. self.assertAlmostEqual(diff, 3600, delta=1)
  73. @unittest.skipIf(WINDOWS, "broken on WINDOWS") # TODO: fix it
  74. def test_proc_create_time(self):
  75. # Test that Process.create_time() reflects system clock
  76. # updates. On systems such as Linux this is added on top of the
  77. # process monotonic time returned by the kernel.
  78. t1 = psutil.Process().create_time()
  79. self.update_systime()
  80. t2 = psutil.Process().create_time()
  81. diff = int(t2 - t1)
  82. self.assertAlmostEqual(diff, 3600, delta=1)
  83. @unittest.skipIf(CI_TESTING, "skipped on CI for now") # TODO: fix it
  84. @unittest.skipIf(OPENBSD, "broken on OPENBSD") # TODO: fix it
  85. @unittest.skipIf(FREEBSD, "broken on FREEBSD") # TODO: fix it
  86. def test_proc_ident(self):
  87. p1 = psutil.Process()
  88. self.update_systime()
  89. p2 = psutil.Process()
  90. self.assertEqual(p1._get_ident(), p2._get_ident())
  91. self.assertEqual(p1, p2)
  92. @unittest.skipIf(not LINUX, "LINUX only")
  93. def test_linux_monotonic_proc_time(self):
  94. t1 = psutil.Process()._proc.create_time(monotonic=True)
  95. self.update_systime()
  96. time.sleep(0.05)
  97. t2 = psutil.Process()._proc.create_time(monotonic=True)
  98. self.assertEqual(t1, t2)